2017-08-29 45 views
7

Mam Entity Framework Code Pierwszy model, dla którego stworzyłem statyczną klasę generyczną, która ma metodę wyszukiwania, która jest wywoływana dla każdej pozycji na liście. Przyznawszy, że to jest nad moją głową, pomyślałem, że uczynienie klasy statycznej poprawi przejrzystość kodu, a może nawet wydajność, ponieważ nie trzeba tworzyć instancji w wielu różnych miejscach. Celem tego wszystkiego jest automatyzacja, które właściwości mogą być wyszukiwane, eksportowane itp. Przez użytkownika.Czy wywołanie MakeGenericType (...) kilka razy tworzy nowy typ za każdym razem?

Podstawowe pytanie brzmi: jeśli MakeGenericType (...) zostanie wywołany dla każdej pozycji (potencjalnie 1000s), która ma właściwość typu odniesienia, to typ ogólny dla tej właściwości typu odniesienia wygenerowany raz i zapisany gdzieś lub wygenerowany przez 1000s czasy?

Docenianie wszelkich innych przestępstw związanych z wydajnością lub zapachów z kodem jest mile widziane.

public static class SearchUserVisibleProperties<T> 
{ 
    private static List<PropertyInfo> userVisibleProperties { get; set; } 

    static SearchUserVisibleProperties() 
    { 
     userVisibleProperties = typeof(T).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(UserVisibleAttribute))).ToList(); 
    } 

    public static bool search(T item, string searchString) 
    { 
     foreach (PropertyInfo pInfo in userVisibleProperties) 
     { 
      object value = pInfo.GetValue(item); 
      if (value == null) 
      { 
       continue; 
      } 
      if (pInfo.PropertyType == typeof(string) || pInfo.PropertyType.IsValueType) 
      { 
       ...unrelevant string matching code... 
      } 
      else if ((bool)typeof(SearchUserVisibleProperties<>).MakeGenericType(new Type[] { value.GetType() }).InvokeMember(nameof(search), BindingFlags.InvokeMethod, null, null, new object[] { value, searchString })) 
      { 
       return true; 
      } 
     } 
     return false; 
    } 
} 
+0

Dzięki za pytanie! Zawsze zakładałem, że za każdym razem tworzony jest nowy typ i dodałem własną warstwę pamięci podręcznej, aby temu zapobiec. W rzeczywistości pisałem kod odpowiedzi, oczekując dwukrotnego wydrukowania "Fałszywy". Okazuje się, że mogę teraz bezpiecznie usunąć warstwę pamięci podręcznej! – dasblinkenlight

+1

Należy zauważyć, że 'new Type [] {value.GetType()}' nie jest konieczne, ponieważ parametr 'typeArguments' of' MakeGenericType' jest zadeklarowany ze słowem kluczowym 'params'. Nowa tablica byłaby tworzona w dowolny sposób, ale nie zaśmiecałaby twojego kodu. – dasblinkenlight

+0

Jeśli usuniemy 'new Type [] {value.GetType()}, jego rzutuje' ArgumentException' jako 'class SearchUserVisibleProperties ' ma jeden ogólny parametr, który musi zostać podany, prawda? Więc nie ma oczywistych ulepszeń wydajności/zapachu dla mojego kodu? Odczuwam trochę dumy po montażu przez kilka godzin :). Dziękuję za odpowiedź! – Tom

Odpowiedz

7

Documentation of MakeGenericType sugeruje, że rodzaj zwracane dla tej samej kombinacji ogólnej definicji typu i ogólnych argumentów typu będą takie same:

Type obiekt zwrócony przez MakeGenericType jest taka sama jak Type otrzymanej wywołanie metody GetType wynikowego skonstruowanego typu lub metody GetType dowolnego skonstruowanego typu, który został utworzony z tej samej ogólnej definicji typu przy użyciu tego samego argumentu typu.

Oto mały eksperyment, aby pokazać, że powyższe jest poprawna: