2010-10-14 18 views
22

के साथ काम करना मैं एक ऐसी विधि को कॉल कर रहा हूं जो एक सूची चर लौटाता है जिसमें सी # बेनामी टाइप ऑब्जेक्ट होते हैं। उदाहरण के लिए:सी # बेनामी प्रकार

List<object> list = new List<object>(); 
foreach (Contact c in allContacts) { 
    list.Add(new { 
     ContactID = c.ContactID, 
     FullName = c.FullName 
    }); 
} 
return list; 

मैं कैसे कोड मैं की तरह पर काम कर रहा हूँ, उदाहरण के लिए में इस प्रकार के गुण को संदर्भित करते

foreach (object o in list) { 
    Console.WriteLine(o.ContactID); 
} 

मुझे पता है कि मेरी नमूना संभव नहीं है, मैं केवल करने के लिए इस तरह से लिखा है कहें कि मुझे अनाम प्रकार की प्रत्येक संपत्ति को बिल्कुल पहचानने की आवश्यकता है।

धन्यवाद!

समाधान:

सिर्फ जवाब में से एक सही है और/या एक काम कर समाधान सुझाव देते हैं। मैं ग्रेग उत्तर के विकल्प 3 का उपयोग करने के लिए समाप्त हो गया है। और मैंने .NET 4.0 में dynamic के बारे में कुछ बहुत रोचक सीखा!

+0

संभव डुप्लिकेट [पहुँचने सी # बेनामी प्रकार वस्तुओं] (http://stackoverflow.com/questions/713521/accessing-c-sharp-anonymous-type-objects) – nawfal

उत्तर

32

आप किसी अज्ञात प्रकार की सूची वापस नहीं कर सकते हैं, इसे object की एक सूची होगी। इस प्रकार आप प्रकार की जानकारी खो देंगे।

विकल्प 1
अनाम प्रकार का उपयोग न करें। यदि आप एक से अधिक विधि में किसी अज्ञात प्रकार का उपयोग करने का प्रयास कर रहे हैं, तो एक असली कक्षा बनाएं।

विकल्प 2
object करने के लिए अपने गुमनाम प्रकार खिन्न न करें। (एक विधि में होना चाहिए)

var list = allContacts 
      .Select(c => new { c.ContactID, c.FullName }) 
      .ToList(); 

foreach (var o in list) { 
    Console.WriteLine(o.ContactID); 
} 

विकल्प 3
उपयोग डायनामिक कीवर्ड। (.NET 4 आवश्यक)

foreach (dynamic o in list) { 
    Console.WriteLine(o.ContactID); 
} 

विकल्प 4
उपयोग कुछ गंदा प्रतिबिंब।

+1

विकल्प 5. दो आइटम टुपल्स की एक सूची लौटाएं (उदा: 'सूची <ट्यूपल > ')। (लेकिन विकल्प 1 के लिए जाएं।) –

+0

विकल्प 3 कहता है कि मुझे दीनामी रनटाइम बाइंडर याद आती है। वो क्या है? क्या मुझे कुछ आयात करना चाहिए? – Lorenzo

+3

+1 विकल्प 1 वास्तव में विभिन्न तरीकों से इस प्रकार का पुन: उपयोग करने के लिए सबसे अच्छा है। –

3
foreach (var o in list) { 
    Console.WriteLine(o.ContactID); 
} 

यह केवल काम करेंगे अगर सूची IEnumerable<anonymous type> है, इस तरह:

var list = allContacts.Select(c => new { 
     ContactID = c.ContactID, 
     FullName = c.FullName 
    }); 
} 

लेकिन आप गुमनाम प्रकार वापस नहीं लौट सकते, क्योंकि आप वापसी प्रकार को परिभाषित करना होगा (आप var वापस नहीं कर सकते हैं) और अनाम प्रकारों के नाम नहीं हो सकते हैं। यदि आप इसे पास करना चाहते हैं तो आपको गैर-अनाम प्रकार बनाना चाहिए। असल में गुमनाम प्रकारों का उपयोग बहुत अधिक नहीं किया जाना चाहिए, प्रश्नों के अंदर छोड़कर।

+1

आप 'IEnumerable <अनाम प्रकार>' – Greg

+0

वापस नहीं लौटा सकते हैं वापसी मुझे एक चेतावनी देती है जो IENumerable <बेनामी टाइप # 1> और सूची के बीच एक अंतर्निहित रूपांतरण नहीं कर सकती है। मुझे अपना तरीका हस्ताक्षर कैसे बदलना है? – Lorenzo

+1

@Lorenzo जैसा कि इसका उल्लेख किया गया था, आप अनाम प्रकार वापस नहीं कर सकते हैं, क्योंकि आपको रिटर्न प्रकार को परिभाषित करना होगा और अनाम प्रकारों के नाम नहीं हो सकते हैं। यदि आप इसे पास करना चाहते हैं तो आपको गैर-अनाम प्रकार बनाना चाहिए। असल में गुमनाम प्रकारों का उपयोग बहुत अधिक नहीं किया जाना चाहिए, प्रश्नों के अंदर छोड़कर। – Andrey

1

आप इसे अज्ञात प्रकारों से नहीं कर सकते हैं। बस एक संपर्क वर्ग/संरचना बनाएँ और इसका उपयोग करें।

List<object> list = new List<object>(); 
foreach (Contact c in allContacts) { 
    list.Add(c); 
} 

तो फिर तुम यह कर सकते हैं:

foreach (var o in list) { 
    Console.WriteLine(o.ContactID); 
} 

...या इस:

List<Contact> list = new List<Contact>(); 
foreach (Contact c in allContacts) { 
    list.Add(c); 
} 

संपादित करें:: छूटी सवाल का अनिवार्य हिस्सा

foreach (object o in list) { 
    Console.WriteLine(((Contact)o).ContactID); //Gives intellisense 
} 
बेशक

आप उस मामले में सिर्फ एक संपर्क सूची के बजाय एक वस्तु सूची बनाने के लिए क्या करना चाहिए। अब तय
संपादित करें: अभी तक बदला गया जवाब। ऊपर देखो।

+0

ओ प्रकार का संपर्क नहीं है, यह एक अनाम प्रकार है। –

+0

यह गलत है। o 'संपर्क' का उदाहरण नहीं है, लेकिन अनाम प्रकार – Andrey

+0

का उदाहरण ओह, उस भाग को याद किया। इसे बहुत तेज़ी से पढ़ें। अन्य सही हैं। 'Var' का प्रयोग करें। –

0

प्रत्येक निर्माण के लिए में वर के साथ वस्तु की जगह

+4

'सूची ' क्या आप सुझाव देते हैं? – Andrey

2

काम कर सकते हैं तो आप इस तरह एक विधि है:

List<object> GetContactInfo() { 
    List<object> list = new List<object>(); 
    foreach (Contact c in allContacts) { 
     list.Add(new { 
      ContactID = c.ContactID, 
      FullName = c.FullName 
     }); 
    } 
    return list; 
    } 

आप वास्तव में ऐसा नहीं करना चाहिए, लेकिन वहाँ एक very ugly and not future-proof तकनीक है कि आप उपयोग कर सकते हैं :

static T CastByExample<T>(object target, T example) { 
    return (T)target; 
    } 

    // ..... 

    var example = new { ContactID = 0, FullName = "" }; 
    foreach (var o in GetContactInfo()) { 
    var c = CastByExample(o, example); 
    Console.WriteLine(c.ContactID); 
    } 

यह इस तथ्य पर निर्भर करता है (बदल सकते हैं जो!) कि संकलक प्रकार है कि एक ही "आकार" के लिए (गुण नाम और प्रकार) गुमनाम प्रकार पुनः उपयोग कर लेता । चूंकि आपका "उदाहरण" विधि में प्रकार के "आकार" से मेल खाता है, उसी प्रकार का पुन: उपयोग किया जाता है।

सी # 4 में गतिशील चर इस हल करने का सबसे अच्छा तरीका हैं।

+8

यह अजीब, अभी तक आकर्षक है। – Greg

-1

मैं

allContacts 
.Select(c => new { c.ContactID, c.FullName }) 
.ToList() 
.ForEach(c => { 
    ...do stuff; 
}); 

तो का उपयोग आप न सब पर घोषित करने के लिए की आवश्यकता होगी। मेरा मानना ​​है कि कम घोषणा, कम सेमी-कोलन कम बग की ओर जाता है

+1

मुझे लगता है कि आप असली सवाल याद कर चुके हैं। कृपया इसे फिर से ध्यान से पढ़ें – Lorenzo

0

मैं जानता हूँ कि मैं पार्टी के लिए देर हो रही है, लेकिन मैं और somthing शोध और इस article जो आपके प्रश्न के उत्तर मिल गया।

ऑब्जेक्ट्स की सूची को अनाम प्रकार में वापस डालना संभव है।

public static void Main() 
    { 
     foreach (object item in GetList()) 
     { 
      var x = Cast(item, new { ContactID = 0, FullName = "" }); 
      Console.WriteLine(x.ContactID + " " + x.FullName); 
     } 

    } 

    public static IEnumerable<object> GetList() 
    { 
     yield return new { ContactID = 4, FullName = "Jack Smith" }; 
     yield return new { ContactID = 5, FullName = "John Doe" }; 
    } 

    public static T Cast<T>(object obj, T type) 
    { 
     return (T)obj; 
    } 
0

सूची वापस

public static void Main() 
{ 
    foreach (object item in GetList()) 
    { 
     var x = Cast(item, new { ContactID = 0, FullName = "" }); 
     Console.WriteLine(x.ContactID + " " + x.FullName); 
    } 

} 

public static IEnumerable<object> GetList() 
{ 
    yield return new { ContactID = 4, FullName = "Jack Smith" }; 
    yield return new { ContactID = 5, FullName = "John Doe" }; 
} 

public static T Cast<T>(object obj, T type) 
{ 
    return (T)obj; 
} 
की
संबंधित मुद्दे