2008-08-21 26 views
5

मेरे पास कक्षाओं का संग्रह है जो मैंने बनाए गए एक अमूर्त वर्ग से प्राप्त किया है। मैं अपने अमूर्त वर्ग के ठोस कार्यान्वयन के उदाहरण बनाने के लिए अमूर्त वर्ग का कारखाना के रूप में उपयोग करना चाहता हूं।क्या कोई कन्स्ट्रक्टर केवल सी # में अभिभावक वर्ग के लिए दृश्यमान बनाने का कोई तरीका है?

क्या माता-पिता वर्ग को छोड़कर सभी कोड से कन्स्ट्रक्टर को छिपाने का कोई तरीका है।

मैं इस मूल रूप से

public abstract class AbstractClass 
{ 
    public static AbstractClass MakeAbstractClass(string args) 
    { 
     if (args == "a") 
      return new ConcreteClassA(); 
     if (args == "b") 
      return new ConcreteClassB(); 
    } 
} 

public class ConcreteClassA : AbstractClass 
{ 
} 

public class ConcreteClassB : AbstractClass 
{ 
} 

करना चाहते हैं लेकिन मैं सीधे 2 ठोस वर्ग instantiating से किसी को रोकने के लिए चाहते हैं। मैं यह सुनिश्चित करना चाहता हूं कि केवल MakeAbstractClass() विधि बेस क्लास को तुरंत चालू कर सके। क्या इसे करने का कोई तरीका है?

अद्यतन
मैं सार वर्ग के बाहर से ConcreteClassA के किसी भी विशिष्ट विधियों या बी का उपयोग करने की जरूरत नहीं है। मुझे केवल अपनी सार कक्षाओं के सार्वजनिक तरीकों की आवश्यकता है। मुझे कंक्रीट कक्षाओं को तत्काल होने से रोकने की ज़रूरत नहीं है, मैं केवल इससे बचने की कोशिश कर रहा हूं क्योंकि वे कोई नया सार्वजनिक इंटरफेस प्रदान नहीं करते हैं, केवल अमूर्त वर्ग के लिए कुछ विशिष्ट चीजों के अलग-अलग कार्यान्वयन।

मेरे लिए, सबसे आसान समाधान make child classes as samjudson mentioned है। मैं इससे बचना चाहता हूं हालांकि यह मेरी अमूर्त कक्षा 'फ़ाइल को जितना बड़ा होगा उतना बड़ा कर देगा। मैं कक्षाओं को संगठन के लिए कुछ फाइलों पर विभाजित रखना चाहता हूं।

मुझे लगता है कि वहाँ इस के लिए कोई आसान समाधान ...

उत्तर

2

आप इस तरह उप वर्गों बच्चे कक्षाएं, कुछ कर सकते हैं:

public abstract class AbstractClass 
{ 
    public static AbstractClass MakeAbstractClass(string args) 
    { 
     if (args == "a") 
      return new ConcreteClassA(); 
     if (args == "b") 
      return new ConcreteClassB(); 
    } 

    private class ConcreteClassA : AbstractClass 
    { 
    } 

    private class ConcreteClassB : AbstractClass 
    { 
    } 
} 

@Vaibhav यह वास्तव में क्या मतलब है कि कक्षाएं भी छिपे हुए हैं। लेकिन यह है कि जहां तक ​​मैं कन्स्ट्रक्टर को पूरी तरह छिपाने का एकमात्र तरीका जानता हूं।

संपादित करें: जैसा कि अन्य ने उल्लेख किया है कि वही चीज प्रतिबिंब का उपयोग करके पूरा की जा सकती है, जो वास्तव में आप जो मामला बनना चाहते हैं उसके करीब हो सकते हैं - उदाहरण के लिए उपर्युक्त विधि कंक्रीट कक्षाओं पर उसी फ़ाइल के अंदर होती है सार वर्ग, जो शायद बहुत सुविधाजनक नहीं है। ऐसा कहकर कि यह तरीका एक अच्छा 'हैक' है, और अच्छा है कि कंक्रीट कक्षाओं की संख्या और जटिलता कम है।

+0

अच्छा उदाहरण है, लेकिन थोड़ा और नामकरण करना। नेटी और कोडिंग-मानकों के लिए इसे "CreateAbstractClass (स्ट्रिंग args)" कहें :) –

1

नहीं, मैं नहीं लगता है कि हम ऐसा कर सकते हैं करते हैं।

3

यदि कक्षाएं एक ही असेंबली में हैं, तो क्या आप रचनाकारों को आंतरिक नहीं बना सकते?

0

क्या आप वास्तव में यह करने के लिए की आवश्यकता है? यदि आप किसी प्रकार के छद्म फैक्ट्री पैटर्न का उपयोग कर रहे हैं, तो इसके लिए एक सच्ची डिज़ाइन की आवश्यकता नहीं है, तो आप केवल अपने कोड को समझने, बनाए रखने और विस्तार करने के लिए कठिन बना रहे हैं।

यदि आपको ऐसा करने की आवश्यकता नहीं है, तो बस एक वास्तविक फैक्ट्री पैटर्न लागू करें। या, अधिक ALTy, एक डीआई/आईओसी ढांचे का उपयोग करें।

6

मेरे लिए, सबसे सरल समाधान samjudson उल्लेख किया मेकअप बच्चे वर्गों के लिए है। मैं इस से बचना चाहता हूं, हालांकि यह अमूर्त वर्ग 'फ़ाइल को से बहुत बड़ा बना देगा, जिसे मैं चाहता हूं।मैं कक्षाओं को संगठन के लिए कुछ फ़ाइलों पर विभाजित करना चाहता हूं।

कोई बात नहीं, बस आंशिक कीवर्ड का उपयोग करें और अपनी इच्छानुसार आप के रूप में कई फ़ाइलों में अपने भीतर के वर्गों विभाजित कर सकते हैं। आपको इसे एक ही फाइल में रखना नहीं है।

पिछला जवाब:

यह संभव है, लेकिन केवल प्रतिबिंब

public abstract class AbstractClass 
{ 
    public static AbstractClass MakeAbstractClass(string args) 
    { 
     if (args == "a") 
      return (AbstractClass)Activator.CreateInstance(typeof(ConcreteClassA), true); 
     if (args == "b") 
      return (AbstractClass)Activator.CreateInstance(typeof(ConcreteClassB), true); 
    } 
} 

public class ConcreteClassA : AbstractClass 
{ 
    private ConcreteClassA() 
    { 
    } 
} 

public class ConcreteClassB : AbstractClass 
{ 
    private ConcreteClassB() 
    { 
    } 
} 

साथ और यहाँ, एक और पैटर्न है बिना बदसूरत MakeAbstractClass (स्ट्रिंग args)

public abstract class AbstractClass<T> where T : AbstractClass<T> 
{ 
    public static T MakeAbstractClass() 
    { 
     T value = (T)Activator.CreateInstance(typeof(T), true); 
     // your processing logic 
     return value; 
    } 
} 

public class ConcreteClassA : AbstractClass<ConcreteClassA> 
{ 
    private ConcreteClassA() 
    { 
    } 
} 

public class ConcreteClassB : AbstractClass<ConcreteClassB> 
{ 
    private ConcreteClassB() 
    { 
    } 
} 
-2

क्या आप डिफ़ॉल्ट कन्स्ट्रक्टर को बनाने के लिए इसे करने की आवश्यकता है। यदि कक्षाएं एक ही असेंबली में नहीं हैं तो आंतरिक को सार्वजनिक में बदला जा सकता है।

public abstract class AbstractClass{ 

public static AbstractClass MakeAbstractClass(string args) 
{ 
    if (args == "a") 
     return ConcreteClassA().GetConcreteClassA(); 
    if (args == "b") 
     return ConcreteClassB().GetConcreteClassB(); 
} 
} 

public class ConcreteClassA : AbstractClass 
{ 
    private ConcreteClassA(){} 

    internal static ConcreteClassA GetConcreteClassA(){ 
     return ConcreteClassA(); 
    } 
} 

public class ConcreteClassB : AbstractClass 
{ 
    private ConcreteClassB(){} 
    internal static ConcreteClassB Get ConcreteClassB(){ 
     return ConcreteClassB(); 
    } 

} 
0

आप कई फाइलों में एक वर्ग के लिए कोड बंटवारे के लिए कीवर्ड partial का उपयोग नहीं कर सकते हैं?

0

यदि आप इस वर्ग का एक अलग सेवा असेंबली में उपयोग कर रहे हैं, तो आप आंतरिक कीवर्ड का उपयोग कर सकते हैं।

public class AbstractClass 
{ 
    public AbstractClass ClassFactory(string args) 
    { 
     switch (args) 
     { 
      case "A": 
       return new ConcreteClassA();    
      case "B": 
       return new ConcreteClassB();    
      default: 
       return null; 
     } 
    } 
} 

public class ConcreteClassA : AbstractClass 
{ 
    internal ConcreteClassA(){ } 
} 

public class ConcreteClassB : AbstractClass 
{ 
    internal ConcreteClassB() {} 
} 
1

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

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

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