2011-04-06 11 views
13

संपादितप्रतिबिंब के साथ IEnumerable <T> के लिए जांच की जा रही

इस सवाल का नंगे हड्डियों संस्करण, अगर मैं कुछ object o है, मैं कैसे करता है, तो ओ कुछ प्रकार है कि प्रतिबिंब के साथ IEnumerable<string>लागू करता है की है देखने के लिए जाँच करेगा है? मूल प्रश्न अधिक विशिष्ट है, लेकिन उपरोक्त का उत्तर उतना ही अच्छा होगा। क्षमा करें यदि मैं इस सवाल

अंत संपादित

निम्नलिखित एक काल्पनिक ValueInjecter POC है पर बहुत ज्यादा विस्तार दे दी है। बहुत नीचे isCollectionMapping विधि को छोड़कर सबकुछ अच्छी तरह से काम करता है। मैं इसे वापस लौटने की कोशिश कर रहा हूं यदि केवल और यदि स्रोत और लक्ष्य संपत्ति दोनों कोई वस्तु है जो IEnumerable<respectiveTypes> लागू करती है।

मैंने IsAssignableFrom और IsInstanceOfType भी कोशिश की है, लेकिन न ही काम करने लगता है।

सबकुछ तब से काम करता है जब मैं विधि "बच्चों" के गुणों के लिए स्पष्ट रूप से जांचने के लिए विधि की दूसरी पंक्ति को अनमोल करता हूं, यह ठीक काम करता है।

नोट - मुझे पता है कि इस उदाहरण के साथ समस्याएं हैं। अर्थात्, मैं किसी भी पुराने IEnumerable<> की जांच करने की कोशिश कर रहा हूं लेकिन अभी भी List<> लौटने के लिए हमेशा पर्याप्त जानकारी प्राप्त कर रहा हूं; यह इस बिंदु पर अवधारणा का सिर्फ एक मूर्ख प्रमाण है।

[TestClass] 
public class UnitTest1 { 

    [TestMethod] 
    public void TestMethod1() { 
     List<string> strings = new List<string>(); 

     Subject S = new Subject() { 
      id = 1, 
      SubjectName = "S1", 
      Children = { new Subject() { id = 2, SubjectName = "S1a" }, 
         new Subject() { id = 3, SubjectName = "S1b", Children = { new Subject() { id = 4} } } } 
     }; 

     SubjectViewModel VM = (SubjectViewModel)new SubjectViewModel().InjectFrom<CollectionToCollection>(S); ; 


     Assert.AreEqual(2, VM.Children.Count); 
     Assert.AreEqual(1, VM.Children.Single(s => s.id == 3).Children.Count); 
    } 
} 


public class Subject { 
    public Subject() { 
     Children = new List<Subject>(); 
    } 

    public string SubjectName { get; set; } 
    public int id { get; set; } 

    public List<Subject> Children { get; set; } 
} 

public class SubjectViewModel { 
    public SubjectViewModel() { 
     Children = new List<SubjectViewModel>(); 
    } 

    public string SubjectName { get; set; } 
    public int id { get; set; } 

    public List<SubjectViewModel> Children { get; set; } 
} 

public class CollectionToCollection : Omu.ValueInjecter.ConventionInjection { 
    protected override bool Match(ConventionInfo c) { 
     return c.TargetProp.Name == c.SourceProp.Name; 
    } 

    protected override object SetValue(ConventionInfo c) { 
     if (isCollectionMapping(c)) 
      return (c.SourceProp.Value as IEnumerable<Subject>).Select(s => (SubjectViewModel)(new SubjectViewModel().InjectFrom<CollectionToCollection>(s))).ToList(); 
     else 
      return c.SourceProp.Value; 
    } 

    private bool isCollectionMapping(ConventionInfo c) { 
     return c.SourceProp.Value.GetType().IsInstanceOfType(typeof(IEnumerable<Subject>)) && c.TargetProp.Value.GetType().IsAssignableFrom(typeof(IEnumerable<SubjectViewModel>)); 

     //return c.SourceProp.Name == "Children" && c.TargetProp.Name == "Children"; 
    } 
} 

उत्तर

27

अगर मैं किसी वस्तु o है, मैं अगर o कुछ प्रकार है कि लागू करता IEnumerable<string> की है कि कैसे को देखने के लिए जांच चाहते हैं?

के रूप में सरल रूप में:

o is IEnumerable<string> 

वैसे, अपने वर्तमान कोड काम नहीं कर रहा है क्योंकि यह पीछे assignability रिश्ते की परीक्षण (जैसे कि विधि IsAssignableTo कहा जाता था) है, अर्थातयह मानते हुए किया जाता है कि:

Bar bar = ... 
Foo foo = bar 

का अर्थ है:

typeof(Bar).IsAssignableFrom(typeof(Foo)) // wrong 

हकीकत में, वास्तविक निहितार्थ यह है कि है:

typeof(Foo).IsAssignableFrom(typeof(Bar)) 

अर्थात्, मैं किसी भी के लिए जाँच करने के लिए कोशिश कर रहा हूँ पुराना IEnumerable<>:

,210

इस मामले में, आप प्रकार सामान्य इंटरफ़ेस का एक निर्माण किया संस्करण को भी लागू करता है, तो परीक्षण की आवश्यकता:

o.GetType() 
.GetInterfaces() 
.Any(t => t.IsGenericType 
     && t.GetGenericTypeDefinition() == typeof(IEnumerable<>)) 
10

इस सवाल का नंगे हड्डियों संस्करण, अगर मैं किसी वस्तु ओ है, मैं कैसे करता है, तो ओ कुछ प्रकार है कि IEnumerable<string> लागू करता है की है देखने के लिए जाँच होगा?

इस तरह

:

object o = whatever; 
bool isSequenceOfStrings = o is IEnumerable<string>; 
+0

मुझे लगता है कि मुझे बहुत अधिक जानकारी, और बहुत कम के बीच संतुलन का सामना करना मुश्किल समय लगता है। मुझे प्रतिबिंब के साथ ऐसा करने की ज़रूरत है। भ्रम के लिए खेद है, एरिक। :) –

+0

@Adam: फिर सवाल क्या है? क्या सवाल है "अगर मेरे पास कुछ टाइप ऑब्जेक्ट है तो मैं यह देखने के लिए कैसे जांच करूं कि टी आईएनमेर्यूरेबल लागू करता है?" या सवाल है "अगर मेरे पास कुछ प्रकार का ऑब्जेक्ट टी है तो मैं कैसे जांच करूं कि टी आईएन्यूमेरेबल है?" या सवाल है "अगर मेरे पास कुछ प्रकार का ऑब्जेक्ट टी है तो मैं कैसे जांचूंगा कि टी IENumerable के बराबर है?" या ... वे सभी अलग-अलग प्रश्न हैं। जब आप उस प्रश्न से पूछें जो आपको वास्तव में रूचि है तो आपको वह जवाब मिलेगा जो आप चाहते हैं। –

+0

आपको प्रतिबिंब के साथ ऐसा करने की आवश्यकता क्यों है? –

5

मैं कुछ खो सकते हैं (अपने पूरे कोड नमूना पढ़ा नहीं था), लेकिन यह 'नहीं करता है ऐसा लगता है कि आपको यहां प्रतिबिंब की आवश्यकता है।

कैसे बस का उपयोग कर के बारे में:

if (c.SourceProp.Value is IEnumerable<Subject>) 
    return true; 

आप विशिष्ट प्रकार पता नहीं है, जेनरिक का उपयोग करें:

public bool MyFunction<T>(...) 
{ 
    if (c.SourceProp.Value is IEnumerable<T>) 
     return true; 
} 

या आप इंटरफेस का उपयोग करने की आवश्यकता है, यह इस तरह से करते हैं (एक कास्ट बचाता है):

var enumerable = c.SourceProp.Value as IEnumerable<string>; 
if (enumerable != null) 
{ 
    // Use IEnumerable<string> 
    return true; 
} 

return false; 
+0

धन्यवाद, हाँ, सरल काम किया होगा। यकीन नहीं है कि मैं इसे कैसे चूक गया। +1 –

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