Я использую отражение, чтобы перебрать Type
свойства и установить определенные типы по умолчанию. Теперь я мог бы переключить тип и установить default(Type)
явно, но я бы предпочел сделать это в одну строку. Есть ли программный эквивалент дефолта?
c#
reflection
default
tags2k
источник
источник
Ответы:
В более новой версии .net, такой как стандарт .net,
type.IsValueType
необходимо записать какtype.GetTypeInfo().IsValueType
источник
default(T) != (T)(object)default(T) && !(default(T) != default(T))
есть аргумент, в противном случае не имеет значения, упакован он или нет, поскольку они эквивалентны.default(T) != default(T)
возвращение ложным, и это обман! =)Array.CreateInstance(type, length)
.Почему бы не вызвать метод, который возвращает default (T) с отражением? Вы можете использовать GetDefault любого типа с:
источник
nameof(GetDefaultGeneric)
если вы можете, вместо"GetDefaultGeneric"
Вы можете использовать
PropertyInfo.SetValue(obj, null)
. Если вызывается для типа значения, он даст вам значение по умолчанию. Это поведение описано в .NET 4.0 и .NET 4.5 .источник
Если вы используете .NET 4.0 или выше и вам нужна программная версия, которая не является кодификацией правил, определенных вне кода , вы можете создавать
Expression
, компилировать и запускать ее на лету.Следующий метод расширения будет принимать
Type
и получить значение , возвращаемоеdefault(T)
черезDefault
метод наExpression
классе:Вы также должны кешировать вышеуказанное значение на основе
Type
, но учтите, что если вы вызываете это для большого числаType
экземпляров и не используете его постоянно, объем памяти, используемой кешем, может перевесить преимущества.источник
e.Compile()
. Вот и весь смысл выражений.e.Compile()
должен быть кэширован, но при условии, что этот метод примерно в 14 раз быстрее, напримерlong
. См. Gist.github.com/pvginkel/fed5c8512b9dfefc2870c6853bbfbf8b для оценки и результатов.e.Compile()
а неe.Compile()()
? т.е. может ли тип по умолчанию изменить тип во время выполнения? Если нет (как я полагаю, так), вы можете просто сохранить кеш-результат, а не скомпилированное выражение, что должно еще больше повысить производительность.Почему вы говорите, что дженерики за кадром?
источник
Это оптимизированное решение Флема:
источник
return type.IsValueType ? typeDefaults.GetOrAdd(type, Activator.CreateInstance) : null;
Выбранный ответ является хорошим ответом, но будьте осторожны с возвращенным объектом.
Экстраполяция ...
источник
Выражения могут помочь здесь:
Я не тестировал этот фрагмент, но я думаю, что он должен выдавать «типизированные» нули для ссылочных типов.
источник
"typed" nulls
объясните. Какой объект вы возвращаете? Если вы возвращаете объект типаtype
, но его значение равноnull
, тогда у него нет - не может - никакой другой информации, кроме той, которая естьnull
. Вы не можете запроситьnull
значение и выяснить, какой тип он предположительно. Если вы НЕ вернете ноль, но вернетесь ... Я не знаю, что .., тогда это не будет вести себя какnull
.Пока не могу найти ничего простого и элегантного, но у меня есть одна идея: если вы знаете тип свойства, которое хотите установить, вы можете написать свой собственный
default(T)
. Есть два случая -T
это тип значения иT
ссылочный тип. Вы можете увидеть это, проверивT.IsValueType
. ЕслиT
это ссылочный тип, вы можете просто установить егоnull
. ЕслиT
это тип значения, то у него будет конструктор по умолчанию без параметров, который можно вызвать, чтобы получить «пустое» значение.источник
Я делаю ту же задачу, как это.
источник
Эквивалентно ответу Дрора, но как метод расширения:
источник
Небольшие изменения в решении @Rob Fonseca-Ensor : следующий метод расширения также работает на .Net Standard, так как я использую GetRuntimeMethod вместо GetMethod.
... и соответствующий юнит-тест для тех, кто заботится о качестве:
источник
источник
Nullable<T>
типов: он не возвращает эквивалент,default(Nullable<T>)
который должен бытьnull
. Принятый ответ от Дрор работает лучше.Это должно работать:
Nullable<T> a = new Nullable<T>().GetValueOrDefault();
источник