2009-10-18 17 views
11

के पढ़ने/लिखने के गुण प्राप्त करें मुझे किसी अज्ञात प्रकार के सभी गुणों को लाने की आवश्यकता है जिसे लिखा जा सकता है।बेनामी टाइप

जैसे:

var person = new {Name = "Person's Name", Age = 25}; 
Type anonymousType = person.GetType(); 
var properties = anonymousType.GetProperties(BindingFlags.Public | BindingFlags.Instance); 

समस्या यह है कि सभी गुण उनके CanWrite संपत्ति false है। यह गैर अनाम प्रकारों के लिए सच के रूप में वापस आ गया है।
मैंने PropertyInfo.GetSetMethod() पर कॉल करने का भी प्रयास किया है जो null देता है।
मैं कैसे जांच सकता हूं कि संपत्ति को लिखा जा सकता है या नहीं?

संपादित करें: शायद यह जानना पर्याप्त होगा कि कोई प्रकार गुमनाम है या नहीं। प्रतिबिंब का उपयोग करके एक प्रकार अज्ञात है या नहीं, तो मैं कैसे पता लगा सकता हूं?

उत्तर

18

सी # से उत्पन्न अज्ञात प्रकार हमेशा अपरिवर्तनीय हैं, इसलिए लिखने योग्य गुणों का सेट खाली है। वीबी में यह वैकल्पिक है: प्रत्येक संपत्ति को परिवर्तनीय होने के लिए डिफ़ॉल्ट करता है, लेकिन यदि आप Key के साथ इसे उपसर्ग करते हैं तो यह अपरिवर्तनीय है; केवल गुणों को Key का उपयोग करके समानता और हैश कोड जनरेशन के लिए गणना की गई है। व्यक्तिगत रूप से मैं सी # के दृष्टिकोण को पसंद करता हूं।

CanWrite गैर-अज्ञात प्रकारों में गुणों के लिए सत्य के रूप में वापस लौटा - केवल लिखने योग्य लोगों के लिए। गुण केवल पढ़ने के लिए, केवल लिखने, या पढ़ने-लिखने के लिए किया जा सकता है। उदाहरण के लिए:

public class Test 
{ 
    // CanWrite will return false. CanRead will return true. 
    public int ReadOnly { get { return 10; } } 

    // CanWrite will return true. CanRead will return false. 
    public int WriteOnly { set {} } 

    // CanWrite will return true. CanRead will return true. 
    public int ReadWrite { get { return 10; } set {} } 
} 
+0

हाय, "हमेशा नहीं है"? क्या आप उस पर थोड़ा सा विस्तार कर सकते हैं। इसके अलावा मैं भी एक सेट विधि उत्पन्न होने की उम्मीद कर रहा था। क्या संकलक केवल एक सेटटर उत्पन्न करने के लिए पर्याप्त है अगर इसका उपयोग किया जाता है? - धन्यवाद। –

+0

क्या यह जानना संभव है कि प्रतिबिंब का उपयोग कर एक प्रकार अज्ञात है या नहीं? –

+0

आप * सी # द्वारा उत्पन्न अज्ञात प्रकार के साथ एक सेटटर का उपयोग नहीं कर सकते - जैसा कि मैंने कहा है, यह हमेशा अपरिवर्तनीय है। नामित प्रकारों के लिए, उदाहरण के लिए दिखाए गए अनुसार, आपके पास एक सेटटर है या नहीं, घोषणा पर निर्भर करेगा। यह पता लगाने के लिए कि कंपाइलर द्वारा एक प्रकार का निर्माण किया गया था, उस जगह के बारे में एक और SO सवाल है। मैं इसे खोजने की कोशिश करूंगा। –

1

गुमनाम प्रकारों की गुणों को असाइन नहीं किया जा सकता है, इसलिए प्रतिबिंब सही ढंग से रिपोर्ट करता है।

यदि आप संकलित आईएल को देखना चाहते हैं, तो आप देखेंगे कि सी # कोड ऐसा लगता है कि यह सामान्य प्रारंभकर्ता का उपयोग कर रहा है, फिर भी इसे कंपाइलर द्वारा कन्स्ट्रक्टर कॉल के रूप में लिखा जाता है, जो गुणों को होने की अनुमति देता है कक्षा के बाहर गैर लिखने योग्य।

1

मुझे कैसे पता चलेगा कि प्रतिबिंब का उपयोग करके कोई प्रकार अज्ञात है या नहीं?

मैं अगर प्रकार CompilerGenerated विशेषता

2

अगर एक प्रकार के रूप .NET 2.0 क्रम गुमनाम प्रकार का समर्थन नहीं किया अनाम है निर्धारित करने के लिए कोई विश्वसनीय तरीका नहीं है है आप जाँच कर सकते हैं लगता है। "कंपाइलर जेनरेट नाम" के प्रारूप पर निर्भर एक सुरक्षित फिक्स नहीं है क्योंकि यह संकलक के विभिन्न संस्करणों के साथ बदलने की संभावना है।

ऐसा लगता है कि आपने ऊपर दिए गए बयान के साथ "यह कैसे जांच सकता हूं कि संपत्ति को लिखा जा सकता है" के बारे में आप अपने प्रश्न का उत्तर दे सकते हैं: CanWrite गलत है और GetSetMethod (सत्य) शून्य हो जाता है। वे दो संकेत हैं जिन्हें आप संपत्ति को नहीं लिख सकते हैं।

चूंकि हम .NET 2.0 रनटाइम पर हैं, इसलिए सिस्टम पर "IsAnonymous" प्रॉपर्टी नहीं है। टाइप करें ताकि आपके पास किसी अज्ञात प्रकार की पहचान करने के लिए वास्तव में कोई विश्वसनीय तरीका न हो।

0

मैं कैसे लगाऊं कि एक प्रकार प्रतिबिंब का उपयोग गुमनाम है?

बस इस कोड का उपयोग करें।

var isAnonymousType = Attribute.IsDefined(dataType, typeof (CompilerGeneratedAttribute), false) && dataType.IsGenericType && dataType.FullName.Contains("Anonymous") && (dataType.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic; 
+0

यह [उत्तर] (http://stackoverflow.com/a/16349607/945456) सुझाव देता है कि आप केवल 'कंपाइलर जेनरेटेड एट्रिब्यूट' की जांच कर सकते हैं। क्या ये सभी अन्य चेक वास्तव में जरूरी हैं? संपादित करें: ऐसा लगता है कि आपको उसी स्रोत से जानकारी मिली है [उत्तर] (http://stackoverflow.com/a/2483054/945456)? –

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