Korzystam z odbicia, aby przeglądać Type
właściwości a i ustawiać niektóre typy na domyślne. Teraz mógłbym zmienić typ i ustawić default(Type)
jawnie, ale wolałbym to zrobić w jednym wierszu. Czy istnieje programowy odpowiednik wartości domyślnej?
c#
reflection
default
tags2k
źródło
źródło
Odpowiedzi:
W nowszej wersji .net, takiej jak .net standard,
type.IsValueType
należy zapisać jakotype.GetTypeInfo().IsValueType
źródło
default(T) != (T)(object)default(T) && !(default(T) != default(T))
masz argument, w przeciwnym razie nie ma znaczenia, czy jest on zapakowany, czy nie, ponieważ są one równoważne.default(T) != default(T)
zwrot będzie fałszywy, a to jest oszustwo! =)Array.CreateInstance(type, length)
.Dlaczego nie wywołać metody, która zwraca wartość domyślną (T) z odbiciem? Możesz używać GetDefault dowolnego typu z:
źródło
nameof(GetDefaultGeneric)
jeśli możesz, zamiast"GetDefaultGeneric"
Możesz użyć
PropertyInfo.SetValue(obj, null)
. Wywołanie typu wartości daje wartość domyślną. To zachowanie jest udokumentowane w .NET 4.0 i .NET 4.5 .źródło
Jeśli używasz .NET 4.0 lub nowszej wersji i chcesz mieć wersję programową, która nie jest kodyfikacją reguł zdefiniowanych poza kodem , możesz utworzyć
Expression
, skompilować i uruchomić go w locie.Poniższa metoda rozszerzenie będzie trwać
Type
i uzyskać wartość zwracana zdefault(T)
pośrednictwemDefault
metody wExpression
klasie:Powinieneś również buforować powyższą wartość na podstawie
Type
, ale pamiętaj, jeśli wywołujesz to dla dużej liczbyType
instancji, i nie używaj jej stale, pamięć zajęta przez pamięć podręczną może przeważyć korzyści.źródło
e.Compile()
. To jest cały punkt wyrażeń.e.Compile()
należy zapisać w pamięci podręcznej, ale przy założeniu, że metoda ta jest około 14 razy szybsza nplong
. Zobacz test i wyniki na gist.github.com/pvginkel/fed5c8512b9dfefc2870c6853bbfbf8b .e.Compile()
zamiast pamięci podręczneje.Compile()()
? tzn. Czy domyślny typ typu może się zmieniać w czasie wykonywania? Jeśli nie (jak sądzę), możesz po prostu zapisać wynik w pamięci podręcznej zamiast skompilowanego wyrażenia, co powinno jeszcze bardziej poprawić wydajność.Dlaczego mówisz, że generyczne są poza obrazem?
źródło
Jest to zoptymalizowane rozwiązanie Flem:
źródło
return type.IsValueType ? typeDefaults.GetOrAdd(type, Activator.CreateInstance) : null;
Wybrana odpowiedź jest dobrą odpowiedzią, ale uważaj na zwrócony obiekt.
Ekstrapolacja ...
źródło
Wyrażenia mogą tutaj pomóc:
Nie testowałem tego fragmentu, ale myślę, że powinien on wygenerować „typowane” wartości zerowe dla typów referencyjnych.
źródło
"typed" nulls
- wyjaśnić. Jaki przedmiot zwracasz? Jeśli zwrócisz obiekt typutype
, ale jego wartość tonull
, to nie będzie - nie może - mieć żadnych innych informacji poza tym, czym jestnull
. Nie możesz zapytać onull
wartość i dowiedzieć się, jaki to typ. Jeśli NIE zwrócisz null, ale wrócisz ... Nie wiem co ..., to nie będzie taknull
.Nie mogę jeszcze znaleźć niczego prostego i eleganckiego, ale mam jeden pomysł: jeśli znasz typ nieruchomości, którą chcesz ustawić, możesz napisać własną
default(T)
. Istnieją dwa przypadki -T
jest to typ wartości iT
jest typem referencyjnym. Możesz to zobaczyć, zaznaczającT.IsValueType
. JeśliT
jest to typ odniesienia, możesz go po prostu ustawić nanull
. JeśliT
jest typem wartości, będzie miał domyślny konstruktor bez parametrów, który można wywołać, aby uzyskać „pustą” wartość.źródło
Wykonuję takie samo zadanie jak to.
źródło
Odpowiednik odpowiedzi Drora, ale jako metoda rozszerzenia:
źródło
Nieznaczne zmiany w rozwiązaniu @Rob Fonseca-Ensor : Następująca metoda rozszerzenia działa również w .Net Standard, ponieważ używam GetRuntimeMethod zamiast GetMethod.
... i odpowiedni test jednostkowy dla tych, którym zależy na jakości:
źródło
źródło
Nullable<T>
typów: nie zwraca odpowiednika,default(Nullable<T>)
który powinien byćnull
. Odpowiedź zaakceptowana przez Drora działa lepiej.To powinno działać:
Nullable<T> a = new Nullable<T>().GetValueOrDefault();
źródło