2009-10-26 37 views
6

मैंने सोचा कि मैं कुछ का उपयोग करेंगे के साथ Parameterized तरीके से जेनेरिक इंटरफ़ेस (मैं क्या सोचा था) सरल जेनरिक कुछ व्यापार वर्ग पर CRUD लागू करने के लिए। उदाहरण के लिए।सी # इंटरफ़ेस <T> {टी समारोह <T> (टी टी);}: जेनेरिक वापसी प्रकार

public interface IReadable <T> 
{ 
    T Read<T>(string ID); 
} 

और फिर शायद, मैं नोट वर्ग जैसे के साथ सी आर यूडी करने के लिए एक NoteAdapter हो सकता था।

public class NoteAdapter : IReadable<Note> 
{ 
    public Note Read<Note>(string ID) { 
     return new Note(); 
    } 
} 

लेकिन किसी कारण से, अगर मैं दोनों एक सामान्य वापसी प्रकार और एक समारोह में एक ही सामान्य प्रकार के साथ पैरामिट्रीकृत है ते संकलक भ्रमित हो रही है। यही है, अगर मैं करता हूं:

public interface IReadable <T> 
{ 
    void Read<T>(string ID); 
} 
public class NoteAdapter : IReadable<Note> 
{ 
    public void Read<Note>(string ID) { 
     return new Note(); 
    } 
} 

यह ठीक संकलित करता है, हालांकि यह ऐसा नहीं करता है जो मैं चाहता हूं! इसके अलावा, इस:

public interface IReadable <T> 
{ 
    T Read (string ID); 
} 
public class NoteAdapter : IReadable<Note> 
{ 
    public Note Read(string ID) { 
     return new Note(); 
    } 
} 

रूप में अच्छी तरह ठीक काम करता है, हालांकि यह भी आवश्यकताओं संतुष्ट नहीं करता! -- क्यूं कर ? क्योंकि तब मेरे पास एक कक्षा नहीं हो सकती है जो इन इंटरफेस का एक गुच्छा लागू करे ..eg।

public interface IReadable <T>{ 
    T Read (string ID); 
} 
public class UniversalAdapter : IReadable<Note>, IReadable<Customer> ... 
{ 
    public Note Read(string ID) { 
     return new Note(); 
    } 
    public Customer Read(string ID) { 
     return new Customer(); 
    } 
} 

कोज़ यह संकलित नहीं होगा क्योंकि रिटर्न प्रकार विधियों के हस्ताक्षर का हिस्सा नहीं हैं!

मैं यह धारणा थी, सी # में 3,5 +

T Foo(T t); 
T Foo<T> (T t); 
T Foo(<SomeType> someInstance); 

सभी अलग हस्ताक्षर है! मुझे यहां क्या समझ नहीं आ रहा है ?

उत्तर

10

आपने इंटरफ़ेस को ओवरस्फीस्ड किया है। आप इंटरफ़ेस परिभाषा T घोषित है, लेकिन फिर आप redeclare यह विधि की परिभाषा में:

public interface IReadable <T> /* T is declared here */ 
{ 
    T Read<T>(string ID); /* here, you've declare a NEW generic type parameter */ 
          /* that makes this T not the same as the T in IReadable */ 
} 

इस भ्रम के कारण, आप ऊपर एक त्रुटि के साथ समाप्त जब आप इंटरफ़ेस को लागू करने का प्रयास करें।

public class NoteAdapter : IReadable<Note> /* IReadable defines T to be Note */ 
{ 
    public Note Read<Note>(string ID) { /* Here, you're declaring a generic parameter */ 
             /* named Note. This name then conflicts with */ 
             /* the existing type name Note */ 
     return new Note(); 
    } 
} 

इसे ठीक करने के लिए, आप बस Read समारोह से सामान्य पैरामीटर दूर करने के लिए, दोनों इंटरफ़ेस में की जरूरत है, और NoteAdapter कक्षा में:

public interface IReadable <T> 
{ 
    T Read(string ID); 
} 
public class NoteAdapter : IReadable<Note> 
{ 
    public Note Read(string ID) { 
     return new Note(); 
    } 
} 

संपादित करें:

ठीक है, मैंने आपकी बाकी पोस्ट पढ़ी है, और ऐसा लगता है कि आप पहले ही खोज चुके हैं कि यह "काम करता है", लेकिन आपको लगता है कि यह गलत है। क्यूं कर? यह क्या आवश्यकताओं को पूरा नहीं करता है?

+0

आपकी सहायता के लिए Thx .. ऐसा नहीं है कि मैंने सोचा कि क्या काम गलत था, लेकिन मेरी उम्मीद थी कि सीएलआर दो सामान्य प्रकारों को समान करेगा .. एक इंटरफ़ेस और विधि पर एक .. यानी इंटरफ़ेस टी टी के रिटर्न प्रकार के साथ-साथ पढ़ें जैसा ही होगा; लेकिन हकीकत में, यह केवल इंटरफेस के "टी" से मेल खाता है –

3

public interface IReadable <T> { T Read<T>(string ID); }

यहाँ वास्तव में दो अलग-अलग टी: IReadable <T> and T Read<T>(string ID)

शायद सिर्फ

public interface IReadable <T> { T Read(string ID); }?

क्योंकि अन्यथा करने के लिए

public interface IReadable <T> { X Read<X>(string ID); }

Good Generics tutorial

संपादित बराबर है:

हो सकता है आप public interface IReadable <T> { T Read(T ID); } की ज़रूरत है?

+0

हाँ, विशिष्ट होने के लिए आपको जरूरत है: सार्वजनिक इंटरफ़ेस IReadable { टी पढ़ें (स्ट्रिंग आईडी); } तो यहां इंटरफ़ेस प्रकार की परिभाषा के लिए टी केवल एक वास्तविक जेनेरिक पैरामीटर है। – Pete

+0

देखें .. जो संकलित होगा, लेकिन यह वह नहीं है जो मैं ढूंढ रहा हूं .. क्योंकि मेरे पास शायद एक एडाप्टर क्लास होगा जो इरेडेबल एस के समूह का कार्यान्वयन करेगी। इरेडेबल , इरेडेबल इत्यादि .. और यह काम नहीं करेगा क्योंकि उन सभी "टी रीड (स्ट्रिंग आईडी)" एक ही फ़ंक्शन पर मूल्यांकन करेंगे, हालांकि यह "नोट रीड (स्ट्रिंग आईडी)" की अनुमति नहीं देगा; और एक ही कक्षा में "ग्राहक पढ़ें (स्ट्रिंग आईडी)" भी! ~ हमेशा की तरह ... आपकी मदद के लिए! –

+0

सार्वजनिक इंटरफ़ेस इरेडेबल {टी पढ़ें (टी आईडी); }? –

1

सीआईएल does not support वापसी प्रकार द्वारा विधि अधिभार।

+0

आप सही दोस्त हैं .. मेरा बुरा .. मैंने खराब उदाहरण हटा दिया, लेकिन मेरा मुद्दा यह था कि मैं इंटरफ़ेस {टी पढ़ें {स्ट्रिंग आईडी)} - ऐसा लगता है कि यह केवल एक विधि से मेल खाता है इंटरफेस के प्रकार के साथ रिटर्न टाइप या विधि पैरामीटर , लेकिन दोनों नहीं! आपके समय के लिए Thx! –

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