2009-07-21 7 views
36

एक लंबी कहानी को कम करने के लिए मेरे पास एक सी # फ़ंक्शन है जो ऑब्जेक्ट इंस्टेंस के रूप में पास किए गए किसी दिए गए प्रकार पर कार्य करता है। सभी वर्ग ठीक होने पर ठीक काम करता है। हालांकि, जब ऑब्जेक्ट को इंटरफ़ेस के रूप में घोषित किया जाता है, तो मैं वास्तव में ठोस वर्ग को ढूंढना चाहता हूं और उस वर्ग प्रकार पर कार्रवाई करना चाहता हूं।एक इंटरफ़ेस उदाहरण के पीछे कंक्रीट प्रकार ढूँढना

public interface IA 
{ 
    int a { get; set; } 
} 
public class B : IA 
{ 
    public int a { get; set; } 
    public int b { get; set; } 
} 
public class C : IA 
{ 
    public int a { get; set; } 
    public int c { get; set; } 
} 

// snip 

IA myBObject = new B(); 
PerformAction(myBObject); 

IA myCObject = new C(); 
PerformAction(myCObject); 

// snip 

void PerformAction(object myObject) 
{ 
    Type objectType = myObject.GetType(); // Here is where I get typeof(IA) 
    if (objectType.IsInterface) 
    { 
     // I want to determine the actual Concrete Type, i.e. either B or C 
     // objectType = DetermineConcreteType(objectType); 
    } 
    // snip - other actions on objectType 
} 

मैं चाहूँगा के खिलाफ यह पैरामीटर हो PerformAction में कोड प्रतिबिंब का उपयोग करें और देखते हैं कि यह सिर्फ आइए का एक उदाहरण नहीं है करने के लिए:

यहाँ हर जगह का बुरा उदाहरण (गलत संपत्ति आवरण आदि के साथ चमकीला) है लेकिन यह बी का एक उदाहरण है और GetProperties() के माध्यम से संपत्ति "बी" देखने के लिए। अगर मैं .GetType() का उपयोग करता हूं तो मुझे आईए का प्रकार मिलता है - जो मैं चाहता हूं।

प्रदर्शन एक्शन आईए के उदाहरण के अंतर्निहित कंक्रीट प्रकार को कैसे निर्धारित कर सकता है?

कुछ लोग सार कक्षा का उपयोग करने का सुझाव देने के लिए प्रेरित हो सकते हैं लेकिन यह केवल मेरे बुरे उदाहरण की सीमा है। चर मूल रूप से एक इंटरफेस उदाहरण के रूप में घोषित किया जाएगा।

+7

यह एक खराब डिज़ाइन की तरह लगता है। आपको विशेष विधि के बारे में अपनी विधि जानने के बजाय पॉलिमॉर्फिज्म का उपयोग करना चाहिए। यदि आप बाद में जोड़ते हैं तो क्या होता है? –

+4

क्या यह एक इंटरफ़ेस के उद्देश्य को हराने नहीं करता है? आपको इस बात पर ध्यान नहीं देना चाहिए कि जब तक यह इंटरफेस लागू करता है तब तक ठोस प्रकार क्या होता है। –

+2

जॉन और क्रिस को +1, न केवल यह खराब डिजाइन है, लेकिन सवाल कोई समझ नहीं आता है। –

उत्तर

56
Type objectType = myObject.GetType(); 

है जैसे कि यह जाँच अभी भी आप ठोस प्रकार देना चाहिए कर सकते हैं अपने उदाहरण के अनुसार प्रतिबिंब का उपयोग करने की जरूरत नहीं है।

+2

हां, कॉलिंग "myObject.GetType()" कभी भी इंटरफ़ेस प्रकार वापस नहीं करेगा। – TcKs

+0

'PerfomAction' का पैरामीटर 'ऑब्जेक्ट' है, लेकिन वह ऐसा नहीं कर सका: उदाहरण के लिए' IA.getType() '। –

2

आपके पास कभी इंटरफ़ेस के उदाहरण नहीं हो सकते हैं। तो यह निर्धारित करना कि आप एक इंटरफेस या ठोस प्रकार से निपट रहे हैं, यह संभव नहीं है क्योंकि आप हमेशा एक ठोस प्रकार से निपटेंगे। तो मुझे यकीन नहीं है कि आप कोई सवाल समझते हैं। आप वास्तव में क्या करने की कोशिश कर रहे हैं और क्यों?

+2

+1 वास्तव में, वास्तव में उसका उदाहरण ठीक काम करता है। –

5

क्या आप कर रहे हैं वास्तव में डिजाइन बिस्तर है, लेकिन आप यदि आप इस

void PerformAction(object myObject) 
{ 
    B objectType = myObject as B; // Here is where I get typeof(IA) 
    if (objectType != null) 
    { 
     //use objectType.b 
    } 
    else 
    { 
     //Same with A 
    } 
    // snip - other actions on objectType 
} 
+2

यह अभी भी काफी खराब डिजाइन है, क्योंकि आप अभी भी ठोस प्रकार पर निर्भर हैं। यह मोटे तौर पर पहली जगह में इंटरफ़ेस रखने के उद्देश्य को हरा देता है ... – jrista

+0

मैं अपने सिर में चिल्लाना चाहता हूं: "एलएसपी, आईएसपी, डीआईपी !!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!! " – Sebastien

0

शायद तुम is operator

void PerformAction(object myObject) 
{ 
    if (myObject is B) 
    { 
     B myBObject = myObject as B; 
     myBObject.b = 1; 
    } 

    if (myObject is C) 
    { 
     C myCObject = myObject as C; 
     myCObject.c = 1; 
    } 

    // snip - other actions on objectType 
} 
+0

आप इसे दो बार कास्टिंग कर रहे हैं। सीधे 'as' ऑपरेटर का उपयोग करें और बाद में शून्य के लिए जांचें – nawfal

4

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

public interface IA 
{ 
    int a { get; set; } 
    void PerformAction(); 
} 

public class B: IA 
{ 
    public int a { get; set; } 
    public int b { get; set; } 

    public void PerformAction() 
    { 
     // perform action specific to B 
    } 
} 

public class C : IA 
{ 
    public int a { get; set; } 
    public int c { get; set; } 

    public void PerformAction() 
    { 
     // perform action specific to C 
    } 
} 

void PerformActionOn(IA instance) 
{ 
    if (instance == null) throw new ArgumentNullException("instance"); 

    instance.PerformAction(); 

    // Do some other common work... 
} 


B b = new B(); 
C c = new C(); 

PerformActionOn(b); 
PerformActionOn(c); 
संबंधित मुद्दे