2010-09-08 12 views
21

मैं करने के लिए कुछ इसी तरह प्राप्त करने में सक्षम होने की जरूरत है काम करने के लिए निम्नलिखित है:IQueryable OfType <T> जहां टी एक रनटाइम प्रकार

Type type = ??? // something decided at runtime with .GetType or typeof; 
object[] entityList = context.Resources.OfType<type>().ToList(); 

यह संभव है? मैं .NET 4 का उपयोग करने में सक्षम हूं यदि इसमें कुछ भी नया है।

+3

आप अपने आप से पूछना करने के लिए 'क्यों?' ध्यान से करना चाहते हैं। – leppie

+0

यह IQueryable होना चाहिए? आपके उदाहरण से, IENumerable पर्याप्त लगता है। –

+0

@leppie मुझे आपकी बात समझ में नहीं आ रही है .. – Tablet

उत्तर

36

परावर्तन से यह कॉल कर सकते हैं:

MethodInfo method = typeof(Queryable).GetMethod("OfType"); 
MethodInfo generic = method.MakeGenericMethod(new Type[]{ type }); 
// Use .NET 4 covariance 
var result = (IEnumerable<object>) generic.Invoke 
     (null, new object[] { context.Resources }); 
object[] array = result.ToArray(); 

एक वैकल्पिक अपनी खुद की OfTypeAndToArray सामान्य इसके बारे में दोनों बिट्स करने के लिए विधि लिखने के लिए होगा, लेकिन इसके बाद के संस्करण काम करना चाहिए।

+0

स्कीट करता हूं, तो यह एक पौराणिक कथा है - मैं सिर्फ एसक्यूएल प्रोफाइलर का उपयोग करने जा रहा हूं यह देखने के लिए कि यह संग्रह को पुनर्प्राप्त करने के बाद या क्वेरी के हिस्से के रूप में फ़िल्टरिंग कर रहा है .. आप इसका उत्तर भी जानते हैं! – Tablet

+1

@ शाहिन: यह सही काम कर रहा है - यह 'संख्यात्मक। वहाँ' के बजाय 'क्वेरी करने योग्य' कह रहा है। आखिरकार। –

+0

@ स्केट क्या आपको कोई विचार है कि यह प्राप्त होने वाले पहले परिणाम से कैशिंग क्यों हो सकता है? – Tablet

-1
object[] entityList = context.Resources 
           .Where(t=> t.GetType() == type) 
           .ToArray(); 
+0

क्या यह इसके खिलाफ चलने से पहले संसाधनों की पूरी सामग्री वापस नहीं करेगा? इस संदर्भ पर ऑफ टाइप का उपयोग एसक्यूएल में चलाता है (मैं ज़ेंटिटी का उपयोग कर रहा हूं) – Tablet

+0

शाहिन ने जो कहा, इसके अलावा, यह पॉलिमॉर्फिक प्रकारों के लिए भी गलत है। – Timwi

+0

यह कहता है कि जब मैं कोशिश करता हूं और – Tablet

8

ऐसा लगता है कि यहाँ प्रतिबिंब का उपयोग करना होगा ...

public static IEnumerable<object> DyamicOfType<T>(
     this IQueryable<T> input, Type type) 
{ 
    var ofType = typeof(Queryable).GetMethod("OfType", 
        BindingFlags.Static | BindingFlags.Public); 
    var ofTypeT = ofType.MakeGenericMethod(type); 
    return (IEnumerable<object>) ofTypeT.Invoke(null, new object[] { input }); 
} 

Type type = // ...; 
var entityList = context.Resources.DynamicOfType(type).ToList(); 
+0

आपकी मदद के लिए धन्यवाद! – Tablet

0
उपयोग के लिए अपने प्रश्न "जेनेरिक्स" पर

शुद्ध रूप से, नहीं यह संभव नहीं है।

जेनिक्स एक संकलित समय सुविधा है, न कि रनटाइम डिस्कवरी। रनटाइम के लिए, आपको प्रतिबिंब या गतिशील उपयोग करने की आवश्यकता है।

+2

मेह, मुझे "जेनेरिक एक संकलन समय सुविधा" की विशेषता पसंद नहीं है। यह वह है और राक्षसी रूप से एक रनटाइम सुविधा (जावा के विपरीत)। –

+0

आपको यह पसंद नहीं है लेकिन क्या मायने रखता है कि जेनेरिक एक संकलित समय सुविधा है। सामान्य प्रकार टी के ज्ञान के साथ संकलित किया जाता है। यदि आप अन्यथा दिखा सकते हैं, तो कृपया मुझे प्रबुद्ध करें। – Aliostad

+0

यदि यह रनटाइम सुविधा नहीं थी तो MakeGenericType कैसे काम कर सकता है? – Casey

0

किस बारे में ...

public static IList OfTypeToList(this IEnumerable source, Type type) 
    { 
     if (type == null) 
      throw new ArgumentNullException(nameof(type)); 
     return 
      (IList) Activator.CreateInstance(
       typeof(List<>) 
        .MakeGenericType(type), 
       typeof(System.Linq.Enumerable) 
        .GetMethod(nameof(System.Linq.Enumerable.OfType), 
           BindingFlags.Static | BindingFlags.Public) 
        .MakeGenericMethod(type) 
        .Invoke(null, new object[] { source })); 
    } 
संबंधित मुद्दे