2011-05-30 25 views
5

Supose मेरे पास है:कैसे सी # में व्युत्पन्न प्रकार से सामान्य प्रकार के सामान्य तर्क प्रकार प्राप्त करने के लिए

class MyBase<T1, T2>{} 

class MyConcreteBase<T2> : MyBase<ConcreteType1, T2>{} 

class MyConcrete1 : MyConcreteBase<ConcreteType2>{} 

class MyConcrete2 : MyBase<ConcreteType1, ConcreteType2>{} 

मैं T1 और T2 के प्रकार कैसे मिलता है अगर मैं MyConcrete1 या MyConcrete2 या MyConcreteBase या किसी अन्य के कहने है प्रकार के उदाहरण MyBase<T1, T2>

तरह से मैं यह अब मैं .GetType().BaseType जबकि BaseType.Name.StartsWith("MyBase") का उपयोग कर "उठने" कर रहा हूँ विरासत श्रृंखला से और उसके बाद का उपयोग कर से प्राप्त .GetGenericArguments()

012,

यह काम कर रहा है, लेकिन मैं इससे संतुष्ट नहीं हूं, खासकर .StartsWith("MyBase") भाग।

किसी के पास अन्य सुझाव हैं?

+0

यह मेरे उत्तर पर एक त्वरित डाउनवॉटर था। – BoltClock

+0

@ बोल्टक्लॉक गलत प्रश्न का गलत जवाब था। – siride

+0

@ साइराइड: दरअसल। मैं बस इस पर टिप्पणी कर रहा था कि यह कितना तेज़ था :) – BoltClock

उत्तर

2

हाँ, स्ट्रिंग पार्सिंग का उपयोग न करें। आप बस BaseType.IsAssignableFrom(typeof(MyBase<,>)) का उपयोग कर सकते हैं (BaseType और MyBase<,> को रिवर्स करना पड़ सकता है - मुझे हमेशा उलझन मिलता है)।

यह भी अपने आधार वर्ग में गुण के रूप में प्रकार का पर्दाफाश करने के आसान हो सकता है, उदा .:

public Type T1_Type { get { return typeof(T1); } } 
public Type T2_Type { get { return typeof(T2); } } 

मैं पूछने के लिए क्या है, तुम क्यों इन प्रकार के पैरामीटर निकालने के लिए की जरूरत है? यह मेरे लिए एक कोड गंध है।

संपादित करें: मुझे यह जोड़ना चाहिए कि आप जेनिक्स के लिए IsAssignableFrom का उपयोग नहीं कर सकते हैं। एक पूर्ण समाधान के लिए यह उत्तर देखें: How To Detect If Type is Another Generic Type

+0

@siride - मुझे इसकी आवश्यकता है क्योंकि मेरे पास मेरे एमवीसी ऐप में सामान्य रिपोर्ट नियंत्रक है और मेरे पास वहां कार्रवाई है (स्ट्रिंग रिपोर्टनाम)।तब मेरे पास ReportBase और फिर जो भी रिपोर्ट है: ReportBase और फिर वार्षिक जो कुछ भी रिपोर्ट: जो भी रिपोर्ट <जो भी YearlyViewItem> ... और इसी तरह। तो मुझे इसे भंडार में पास करने के लिए टीएनटीटीटी के प्रकार की आवश्यकता है और इसे रिपोर्टबेज.जेनरेट (IQueryable entityQuery) –

+0

@qrow को देने के लिए IQueryable को प्राप्त करने के लिए आवश्यकता है, तो मुझे लगता है कि बेस क्लास में गुणों के रूप में प्रकारों को उजागर करना सबसे अच्छा शर्त है। यह प्रतिबिंब का उपयोग करने से भी बहुत तेज है। – siride

+0

@ साइराइड आप सही हो सकते हैं, यह शायद सबसे आसान समाधान होगा, किसी भी तरह से मैंने उन सामान्य कार्यों के लिए बहुत अधिक प्रतिबिंब का उपयोग किया था, इसलिए मैंने बेस क्लास –

0

अच्छा होगा अगर आप हमें जो कुछ हासिल करना चाहते हैं उसके बारे में कुछ और बताएंगे। अनुमान लगाएं कि आप क्या सोचते हैं, मैं कहूंगा: BaseTypenull तक पूरी विरासत श्रृंखला तक चलें। और फिर सामान्य होने पर प्रत्येक प्रकार की जांच करें और यदि हां, तो GetGenericArguments पर कॉल करें। कुछ भविष्यवाणियों और एक या दो LINQ अभिव्यक्तियों का मामला होना चाहिए।

+0

सरराइड ने इसके उद्देश्य से भी पूछा, ताकि आप वहां मेरी व्याख्या की जांच कर सकें। –

-1

क्या आपका मतलब है: Type.GetGenericArguments Method?

+0

-1 वह पहले से ही उस विधि का उपयोग कर रहा है। – siride

+0

@ साइराइड - मुझे लगता है कि यह अभी भी जवाब है कि "मैं टी 1 और टी 2 के प्रकार कैसे प्राप्त करूं यदि मेरे पास MyConcrete1 या MyConcrete2 या MyConcreteBase या MyBase " –

+0

से व्युत्पन्न प्रकार के किसी अन्य उदाहरण का उदाहरण है लेकिन वह पहले से ही उस हिस्से को जानता है। यह एल्गोरिदम का दूसरा हिस्सा है कि उसे सहायता चाहिए। ऐसा लगता है जैसे किसी ने गणितीय अभिव्यक्ति को पार्स करने के लिए कहा था और व्याकरण के साथ परेशानी हो रही थी और आपने सुझाव दिया कि वह टोकन में चीजों को तोड़ने के लिए रेगेक्स कक्षा का उपयोग करें। तकनीकी रूप से सच है, लेकिन सवाल के लिए सहायक नहीं है। – siride

0

मैं कुछ भी चालाक नहीं सोच सकते हैं, तो मैं शायद सिर्फ ऐसा करने चाहते हैं:

class MyBase<T1, T2> { 
    protected Type GetT1() { return typeof(T1); } 
    protected Type GetT2() { return typeof(T2); } 
} 
3

आप वंशानुगत पदानुक्रम ऊपर चलना और एक GenericType, जो BaseType<,> से निर्माण किया है के लिए देख सकते हैं। प्रयास करें:

var type = c.GetType(); 
Type baseType = type; 
while(null != (baseType = baseType.BaseType)) 
{ 
    if (baseType.IsGenericType) 
    { 
     var generic = baseType.GetGenericTypeDefinition(); 
     if (generic == typeof(MyBase<,>)) 
     { 
      var genericTypes = baseType.GetGenericArguments(); 
      // genericTypes has the type argument used to construct baseType. 
      break; 
     } 
    } 
} 
0

यहाँ एक समारोह है कि किसी भी प्रकार को स्वीकार करेंगे है (यह मानते हुए कि सामान्य मापदंडों के साथ एक आधार वर्ग है) और वापसी कि उदाहरण के आधार वर्ग के सामान्य मानकों के प्रकार:

public Type[] BaseGenericTypes<T>(T instance) 
    { 
     Type instanceType = instance.GetType(); 

     Type objectType = new object().GetType(); 

     while (instanceType.BaseType != objectType) 
     { 
      instanceType = instanceType.BaseType; 
     } 
     return instanceType.GetGenericArguments(); 
    } 

अच्छा इस विधि के बारे में बात यह है कि आपको बेस क्लास या उसके बाद के किसी भी व्युत्पन्न कक्षाओं के बारे में कुछ भी जानने की आवश्यकता नहीं है।

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