2017-08-29 4 views
7

मेरे पास एक एंटिटी फ्रेमवर्क कोड पहला मॉडल है जिसके लिए मैंने एक स्थैतिक जेनेरिक क्लास बनाया है जिसमें एक खोज विधि है जिसे सूची में प्रत्येक आइटम के लिए बुलाया जाता है। यह स्वीकार करते हुए कि यह मेरे सिर पर है, मैंने सोचा कि कक्षा स्थिर बनाने से कोड स्पष्टता में सुधार होगा और यहां तक ​​कि प्रदर्शन भी हो सकता है क्योंकि किसी को कई अलग-अलग स्थानों में उदाहरण नहीं बनाना पड़ता है। इसका लक्ष्य यह है कि उपयोगकर्ता द्वारा कौन सी संपत्तियों को खोजा जा सकता है, निर्यात किया जा सकता है।MakeGenericType (...) को कई बार कॉल करते समय एक नया प्रकार बनाते हैं?

प्राथमिक प्रश्न यह है: यदि मेकजेनरिक टाइप (...) को प्रत्येक आइटम (संभावित रूप से 1000s) के लिए बुलाया जाता है जिसमें संदर्भ प्रकार की संपत्ति होती है, तो उस संदर्भ प्रकार की संपत्ति के लिए एक सामान्य प्रकार होता है जो एक बार उत्पन्न होता है और कहीं भी बचाया जाता है या उत्पन्न होता है बार?

किसी भी अन्य प्रदर्शन अपराध या कोड गंध की ओर इशारा करते हुए सराहना की जाती है।

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

प्रश्न के लिए धन्यवाद! मैंने हमेशा यह माना कि हर बार एक नया प्रकार बनाया जाता है, और इसे रोकने के लिए अपनी खुद की कैशिंग परत जोड़ दी जाती है। वास्तव में, मैं जवाब के लिए कोड लिख रहा था, 'झूठी' दो बार मुद्रित होने की उम्मीद के साथ। यह पता चला है कि मैं अब अपने कैशिंग परत को सुरक्षित रूप से हटा सकता हूं! – dasblinkenlight

+1

ध्यान दें कि 'नया प्रकार [] {value.GetType()} 'आवश्यक नहीं है, क्योंकि' MakeGenericType' के पैरामीटर' प्रकार आर्ग्यूमेंट्स 'को' पैराम्स 'कीवर्ड के साथ घोषित किया गया है। एक नई सरणी किसी भी तरह से बनाई जाएगी, लेकिन यह आपके कोड को अव्यवस्थित नहीं करेगा। – dasblinkenlight

+0

यदि मैं 'नया प्रकार [] {value.GetType()} हटा देता हूं, तो यह 'ArgumentException' को' क्लास सर्च यूज़र विस्बलप्रॉपर्टीज 'के रूप में फेंकता है, जिसमें एक सामान्य पैरामीटर प्रदान किया जाना चाहिए, है ना? तो मेरे कोड के लिए कोई स्पष्ट प्रदर्शन/गंध सुधार नहीं है? कई घंटों के लिए इसे इकट्ठा करने के बाद थोड़ा गर्व महसूस कर रहा है :)। जवाब के लिए धन्यवाद! – Tom

उत्तर

7

Documentation of MakeGenericType पता चलता है कि प्रकार सामान्य प्रकार परिभाषा और सामान्य प्रकार तर्क का एक ही संयोजन के लिए लौट आए ही होगा:

Type वस्तु MakeGenericType द्वारा दिया Type द्वारा प्राप्त रूप में ही है परिणामस्वरूप निर्मित प्रकार की GetType विधि को कॉल करना, या GetType किसी भी प्रकार के प्रकार के विधि को उसी प्रकार के तर्कों का उपयोग करके समान जेनेरिक प्रकार परिभाषा से बनाया गया था।

यहाँ दिखाने के लिए कि ऊपर सही है एक छोटा सा प्रयोग है:

संबंधित मुद्दे