2012-12-22 34 views
9

एरिक लिपर्ट ने http://blogs.msdn.com/b/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx पर अपने ब्लॉग पोस्ट में समझाया है कि बाधाओं को प्रकार अनुमान के लिए क्यों नहीं माना जाता है, जो समझ में आता है कि विधियों को आसानी से बदलकर टाइप बाधाओं को ओवरलोड नहीं किया जा सकता है। हालांकि, मैं दो सामान्य प्रकारों का उपयोग करके किसी ऑब्जेक्ट को तुरंत चालू करने का एक तरीका ढूंढना चाहता हूं, जिसे अनुमानित किया जा सकता है और किसी अन्य प्रकार को निर्दिष्ट किए बिना बाधाओं पर विचार किया जा सकता है।क्या सी # के लिए कोई कामकाज है जो टाइप बाधाओं का उपयोग करके सामान्य प्रकार के तर्कों का अनुमान लगाने में सक्षम नहीं है?

को देखते हुए प्रकार:

public interface I<T> 
{ 
    Other<T> CreateOther(); 
} 

public class C : I<string> 
{ 
    public Other<string> CreateOther() 
    { 
     return new Other<string>(); 
    } 
} 

public class Other<T> 
{ 
} 

और कारखाने:

public static class Factory1 
{ 
    public static Tuple<T, Other<T1>> Create<T, T1>(T o) where T : I<T1> 
    { 
     return new Tuple<T, Other<T1>>(o, o.CreateOther()); 
    } 
} 

निम्नलिखित वांछित कोड संकलन नहीं होगा:

public void WontCompile() 
    { 
     C c = new C(); 
     var v = Factory1.Create(c); // won't compile 
    } 

त्रुटि संदेश "है त्रुटि CS0411: विधि 'yo.Factory1.Create (T)' के लिए तर्क टाइप करें, उपयोग से अनुमानित नहीं किया जा सकता है। टाइप को निर्दिष्ट करने का प्रयास करें स्पष्ट रूप से rguments। ", जो एरिक ने अपने ब्लॉग पोस्ट में क्या कहा था के अनुरूप है। ,

public void SpecifyAllTypes() 
    { 
     C c = new C(); 
     var v = Factory1.Create<C, string>(c); // type is Tuple<C, Other<string>> 
    } 

हम प्रकार तर्क निर्दिष्ट करने के लिए नहीं करना चाहते हैं और हम प्रकार सी बनाए रखने की जरूरत नहीं है:

इस प्रकार, हम बस सामान्य प्रकार तर्क स्पष्ट रूप से निर्दिष्ट कर सकते हैं के रूप में त्रुटि संदेश से पता चलता है हम निम्नलिखित कारखाने का उपयोग कर सकते हैं:

public static class Factory2 
{ 
    public static Tuple<I<T1>, Other<T1>> CreateUntyped<T1>(I<T1> o) 
    { 
     return new Tuple<I<T1>, Other<T1>>(o, o.CreateOther()); 
    } 
} 

और अब निर्दिष्ट करें:

public void Untyped() 
    { 
     C c = new C(); 
     var v = Factory2.CreateUntyped(c); // type is Tuple<I<string>, Other<string>> 
    } 

हो बुनाई, मैं लौटे ऑब्जेक्ट में टाइप सी को बनाए रखना चाहता हूं और प्रकार निर्दिष्ट नहीं करना चाहता हूं।

उत्तर

4

मैं इस समस्या का समाधान के साथ आया था, लेकिन यह एक समाधान है, जहां प्रकार सी की वस्तु एक दो कदम कारखाने कॉल में दो बार प्रयोग किया जाता है की एक kludge हो रहा है।

ऐसा करने के लिए, निम्नलिखित कारखानों उपयोग किया जाता है:

public static class Factory3 
{ 
    public static Factory<T1> CreateFactory<T1>(I<T1> o) 
    { 
     return new Factory<T1>(); 
    } 
} 

public class Factory<T1> 
{ 
    public Tuple<T, Other<T1>> Create<T>(T o) where T : I<T1> 
    { 
     return new Tuple<T, Other<T1>>(o, o.CreateOther()); 
    } 
} 

जो तब के रूप में इस्तेमाल किया जा सकता है:

public void Inferred() 
    { 
     C c = new C(); 
     var v = Factory3.CreateFactory(c).Create(c); // type is Tuple<C, Other<string>> 
    } 

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

क्या इस समस्या का कोई बेहतर समाधान है जहां ऑब्जेक्ट को दो बार उपयोग करने की आवश्यकता नहीं है और प्रकारों को निर्दिष्ट करने की आवश्यकता नहीं है?

संपादित करें: मुझे अभी एहसास हुआ कि, वस्तु को दो बार उपयोग किया जाना चाहिए, दूसरी फैक्ट्री कक्षा की आवश्यकता नहीं है।

public void Inferred() 
{ 
    C c = new C(); 
    var v = Factory.Create(c, c); // type is Tuple<C, Other<string>> 
} 

यह अभी भी आदर्श नहीं है, लेकिन एक दूसरे को बनाने के लिए की तुलना में बेहतर:

public class Factory 
{ 
    public Tuple<T, Other<T1>> Create<T, T1>(T o, I<T1> o2) where T : I<T1> 
    { 
     return new Tuple<T, Other<T1>>(o, o.CreateOther()); 
    } 
} 

यह इस प्रकार के रूप में इस्तेमाल किया जाएगा: बल्कि, दोनों मानकों सिर्फ इस प्रकार एक ही कारखाने विधि में इस्तेमाल किया जा सकता कारखाना वर्ग, और कम से कम XMLDoc टिप्पणियों का उपयोग यह इंगित करने के लिए किया जा सकता है कि दोनों पैरामीटर एक ही वस्तु होनी चाहिए। एक बार फिर, एक पैरामीटर (o2 इस मामले में) केवल T के लिए सीमित प्रकारों का अनुमान लगाने के लिए उपयोग किया जाता है।

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

  • कोई संबंधित समस्या नहीं^_^