2009-06-22 11 views
14

बस सोच अगर वहाँ वैसे भी है सी # में निम्न कोड 3.5 प्रतिनिधित्व करने के लिए:क्या सी # में एक सामान्य कास्ट ऑपरेटर को निम्न तरीके से अधिभारित करना संभव है?

public struct Foo<T> { 

    public Foo(T item) { 
     this.Item = item; 
    } 

    public T Item { get; set; } 

    public static explicit operator Foo<U> (Foo<T> a) 
     where U : T { 

     return new Foo<U>((U)a.Item) 
    } 
} 

धन्यवाद

उत्तर

19

रूपांतरण ऑपरेटर सामान्य नहीं हो सकते हैं।

conversion-operator-declarator: 
    implicit operator type ( type identifier ) 
    explicit operator type ( type identifier )

साथ, कहते हैं इसकी तुलना, एक विधि-हेडर:

विधि हेडर कल्पना खंड 10.10 से, यहाँ एक रूपांतरण-ऑपरेटर-declarator का स्वरूप है : विशेषताओं ऑप्ट विधि-संशोधक ऑप्ट आंशिक ऑप्ट वापसी प्रकार सदस्य नाम प्रकार पैरामीटर-सूची ऑप्ट ( औपचारिक पैरामीटर-सूची ऑप्ट) प्रकार पैरामीटर-बाधाओं-खंड ऑप्ट

(फ़ॉर्मेटिंग के बारे में क्षमा करें - सुनिश्चित नहीं है कि यह कैसे शर्त लगाएं ter।)

ध्यान दें कि ऑपरेटर प्रारूप में एक प्रकार पैरामीटर सूची या पैरामीटर बाधाओं को शामिल नहीं किया गया है।

+2

और यहां तक ​​कि अगर हमने उपयोगकर्ता द्वारा परिभाषित जेनेरिक रूपांतरणों का समर्थन किया है, तो यह अभी भी अवैध होगा। एक रूपांतरण को परिभाषित करना अवैध है जो अंतर्निहित रूपांतरण को प्रतिस्थापित करता है। ऐसा इसलिए होगा यदि टी और यू एक ही प्रकार के थे; आप पहचान रूपांतरण की जगह ले लेंगे। –

+1

चूंकि कंपाइलर द्वारा कास्ट का निर्णय लिया जाता है, यदि टी और यू एक ही प्रकार के थे, तो यह उपयोगकर्ता परिभाषित कलाकार का उपयोग नहीं करेगा, और लीगल हो जाएगा। –

2

आपका कोड लाइन करने पर निर्भर करता: return new Foo<U>((U)a.Item)

आप कहाँ कोशिश करने के लिए एक baseclass आवंटित करने के लिए एक विरासत वर्ग, जो असंभव है।

चलो कहते हैं कि टी (आधार वर्ग) चलो प्रकार Stream की है और यू प्रकार MemoryStream (विरासत में मिला वर्ग) की है, तो आप प्रकार MemoryStream के एक चर करने के लिए एक Stream नहीं सौंप सकते।

+0

निश्चित रूप से आप कर सकते हैं, यदि संदर्भ ऑब्जेक्ट को स्ट्रीम के रूप में मुखौटा करता है, लेकिन यह वास्तव में एक मेमोरीस्ट्रीम है, तो आप निश्चित रूप से इसे मेमोरी स्ट्रीम में डाल सकते हैं। यह एक वैध विधि है, समस्या यह है कि आप वास्तव में ऑपरेटर ओवरलोड पर जेनेरिक बाधाओं को निर्दिष्ट नहीं कर सकते हैं ... – LaserJesus

+0

... यदि आप मेरे पास कोड लेते हैं और ऑपरेटर ओवरलोड के बजाए इसे विधि के रूप में व्यक्त करते हैं तो यह संकलित होगा – LaserJesus

0

ऐसा लगता है कि आप एक contravariant रूपांतरण चाहते का शिकार हो रहा है, लेकिन struct रों अपरिवर्तनीय हैं, रूपांतरण आपको कुछ भी नहीं खरीदता है, आप बस new Foo<U>((U)a.Item) कह सकते हैं क्योंकि @ गिडॉन ने बताया है।

आप Foo बदलने के लिए एक वर्ग के रूप में जाना जाता है, तो हम कुछ फर्क कर सकते हैं:

public interface IFoo<in T> { 
    T Item { 
     set; 
    } 
} 

public class Foo<T>:IFoo<T> { 
    public Foo(T item) { 
     this.Item=item; 
    } 

    public T Item { 
     get; set; 
    } 

    // public static explicit operator Foo<U>(U a) { 
    // return new Foo<U>((U)a.Item); 
    // } 
} 

और चाहते इसका इस्तेमाल:

var foo = new Foo<object>(new object { }); 
IFoo<String> bar = foo; 
bar.Item="123"; 
var b = Object.ReferenceEquals(foo, bar); // true 

वैसे, सामान्य इंटरफेस में विचरण है केवल .netfx 4.0 से उपलब्ध है।

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