2009-04-29 18 views
5

Bellow कोड रहा है के संस्करण सरल है:जेनेरिक वर्ग कारखाने समस्या

public interface IControl<T> 
{ 
    T Value { get; } 
} 

public class BoolControl : IControl<bool> 
{ 
    public bool Value 
    { 
     get { return true; } 
    } 
} 

public class StringControl : IControl<string> 
{ 
    public string Value 
    { 
     get { return ""; } 
    } 
} 
public class ControlFactory 
{ 
    public IControl GetControl(string controlType) 
    { 
     switch (controlType) 
     { 
      case "Bool": 
       return new BoolControl(); 
      case "String": 
       return new StringControl(); 
     } 
     return null; 
    } 
} 

समस्या ControlFactory वर्ग के GetControl विधि में है। क्योंकि यह आईसींट्रोल लौटाता है और मेरे पास केवल आईसीओन्ट्रोल < टी> है जो एक सामान्य इंटरफ़ेस है। मैं टी प्रदान नहीं कर सकता क्योंकि बूल मामले में यह बूल जा रहा है और स्ट्रिंग मामले में यह स्ट्रिंग होने जा रहा है।

कोई विचार मुझे इसे काम करने के लिए क्या करना है?

उत्तर

5

IControl से IControl<T> प्राप्त करें।

public interface IControl<T> : IControl 
{ 
    T Value { get; } 
} 

अद्यतन

अगर मैं तुम्हें missunterstood, और आप एक गैर सामान्य इंटरफ़ेस नहीं करना चाहते, तो आप विधि GetControl() सामान्य बनाने के लिए भी होगा।

public IControl<T> GetControl<T>() 
{ 
    if (typeof(T) == typeof(Boolean)) 
    { 
     return new BoolControl(); // Will not compile. 
    } 
    else if (typeof(T) == typeof(String)) 
    { 
     return new StringControl(); // Will not compile. 
    } 
    else 
    { 
     return null; 
    } 
} 

अब आप समस्या यह है कि नए नियंत्रण परोक्ष IControl<T> लिए casted नहीं किया जा सकता है और आप इस स्पष्ट बनाने के लिए होगा।

public IControl<T> GetControl<T>() 
{ 
    if (typeof(T) == typeof(Boolean)) 
    { 
     return new (IControl<T>)BoolControl(); 
    } 
    else if (typeof(T) == typeof(String)) 
    { 
     return (IControl<T>)new StringControl(); 
    } 
    else 
    { 
     return null; 
    } 
} 

अद्यतन

as IControl<T> से (IControl<T>) के कलाकारों बदल दिया है। यह पसंद किया जाता है क्योंकि अगर as IControl<T> चुपचाप null लौटाता है तो यह एक अपवाद पैदा करेगा।

3
public IControl<T> GetControl<T>() 
{ 
    switch (typeof(T).Name) 
    { 
     case "Bool": 
      return (IControl<T>) new BoolControl(); 
     case "String": 
      return (IControl<T>) new StringControl(); 
    } 
    return null; 
} 

अद्यतन; कोड में कुछ त्रुटियों को सही किया। कक्षा पाने के लिए एक कॉल है:

IControl<bool> boolControl = GetControl<bool>(); 
+3

@ वादीम - मैं दृढ़ता से आपको डैनियल के समाधान का उपयोग करने की सलाह दूंगा, जहां वह स्ट्रिंग का उपयोग करने के बजाय प्रकार की तुलना कर रहा है। प्रकार के नाम का उपयोग करना अधिक त्रुटि प्रवण है। –

+0

@ जोन बी: ​​आप सही हैं; प्रकारों की तुलना करना अधिक मजबूत कोड प्रदान करेगा। मैंने बस काम करने के लिए वादिम के मूल कोड को अद्यतन किया। डैनियल का दृष्टिकोण जाने का बेहतर तरीका है। –

0

रिटर्न प्रकार सामान्य होना चाहिए, ठीक है, यह है। इस बारे में सोचें कि आप इसका उपयोग कैसे करेंगे। दृढ़ता से टाइप की गई वस्तु को लौटने से सामान्य कारखाने की आवश्यकता को रोक दिया जाता है।

यहां तक ​​कि अगर आप यह कर सकते हैं, क्या,

IControl<bool> boolControl = controlFactory.GetControl("bool"); 

के लाभ या एक है कि काम करेगा है

IControl<bool> boolControl = controlFactory.GetControl<bool>("bool"); 

एक विशिष्ट

IControl<bool> boolControl = controlFactory.GetBoolControl("bool"); 

किसी भी तरह से खत्म हो गया, आपके पास क्लाइंट साइड पर स्विच() है। या तो एक ऑब्जेक्ट वापस करें, या एक गैर टाइप टाइप आईसींट्रोल इंटरफ़ेस है।

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