Указанный приведение недействительно только в сборке выпуска из сборки MS.

Я получаю сообщение «Указанное приведение недействительно» при выполнении только сборки выпуска из MSBuild 4.0. Я проверил это, используя сборку выпуска Visual Studio 2012, и не получил этой проблемы. Я также проверил это с помощью отладочной сборки из MSBuild 4.0 и не получил этой проблемы.

Исключение: введите здесь описание изображения

Код

    public abstract class CachedSessionBase : ISessionObject
{
    protected Dictionary<MethodBase, Object> _getAndSetCache = new Dictionary<MethodBase, object>();

    protected TResult SetAndGet<TResult>(ObjectFactory factory, Func<TResult> func)
    {
        StackTrace stackTrace = new StackTrace();
        var methodBase = stackTrace.GetFrame(1).GetMethod();

        if (!_getAndSetCache.ContainsKey(methodBase))
        {
            _getAndSetCache[methodBase] = func.Invoke();
        }

        return (TResult)_getAndSetCache[methodBase];
    }

Ошибка вылетает в этой строке

return (TResult)_getAndSetCache[methodBase];

person Anish    schedule 09.01.2013    source источник
comment
Я бы добавил несколько строк трассировки, чтобы дважды проверить, что все, что выходит из _getAndSetCache[methodBase], на самом деле имеет тип TResult. В конфигурации выпуска (с включенной оптимизацией) кадр стека может измениться, если методы встроены. stackTrace.GetFrame(1).GetMethod() ‹-- такой код не должен запускаться в производство. Существует атрибут, который вы можете применить к членам, чтобы остановить встраивание, но я не могу вспомнить, что это такое... видел, как он использовался в CSLA.NET старого.   -  person Adam Houldsworth    schedule 09.01.2013
comment
Просто чтобы уточнить, я считаю, что проблема в том, что stackTrace.GetFrame(1).GetMethod() возвращает что-то другое в выпуске, чем в отладке. Я бы посоветовал не использовать его, но не могу предложить никаких альтернатив.   -  person Adam Houldsworth    schedule 09.01.2013
comment
можете ли вы зарегистрировать тип объекта перед его возвратом?   -  person Dhawalk    schedule 09.01.2013
comment
StackTrace никогда не следует использовать в рабочем коде. Единственным редким исключением является обработка/регистрация ошибок, которая пытается сделать более интеллектуальный анализ того, что произошло (даже тогда я бы поставил под сомнение достоверность того, что делается)   -  person Chris Marisic    schedule 06.06.2017


Ответы (2)


Вполне вероятно, что стек вызовов отличается от того, что вы ожидаете. Ваш метод может быть встроенным, тогда GetFrame(1) извлекает вызывающего абонента. Когда значение извлекается из словаря, оно имеет другой тип, поскольку предназначено для другого метода.

Вы можете попробовать добавить атрибут [MethodImpl(MethodImplOptions.NoInlining] к SetAndGet, чтобы предотвратить оптимизацию встраивания для метода.

person Mike Zboray    schedule 09.01.2013
comment
+1 место. Это наверняка вызвано оптимизатором кода в конфигурации выпуска. - person Nick Ryan; 09.01.2013
comment
Пробовал этот ответ. Хотя на правильном пути и очень близко, в моем сценарии не сработает. Я использовал stackTrace.GetFrame(1).GetMethod(), чтобы узнать, кто вызывающий абонент. Функция вызывающего абонента оптимизировалась встроенной. Вызывающий объект должен будет реализовать [MethodImpl(MethodImplOptions.NoInlining]. Невозможно заставить вызывающего сделать это, поэтому мне придется искать другое решение. - person Anish; 09.01.2013
comment
@ Аниш Ты действительно должен. Использование StackTrace для чего-то, что не является отладкой, как правило, плохая идея. - person svick; 09.01.2013
comment
Спасибо. попробую другую схему. - person Anish; 09.01.2013

У меня была такая же проблема при запуске nuget pack, который вызывал

Автоматическое определение MSBuild: использование версии msbuild '15.0'...

но проблема была решена запуском dotnet pack, который вызывал

Microsoft (R) Build Engine версии 15.3.409.57025 для .NET Core

person Stephen Buck    schedule 17.10.2017
comment
Для всех, кто использует .net core на Mac, это правильный ответ. Огромное спасибо Стивен - person SteelToe; 12.01.2018