2011-11-30 9 views
5

मेरे पास Identifiable<TId> नामक इंटरफेस है जिसमें दिए गए प्रकार का एक एकल प्रॉपर्टी आईडी है। मैं एक जेनेरिक क्लास बनाना चाहता हूं जो इनमें से एक को टाइप पैरामीटर के रूप में लेता है। यह सामान्य होना चाहिए क्योंकि मैं ठोस प्रकार वापस करना चाहता हूं, इसके भीतर से अन्य सामान्य तरीकों को कॉल करना चाहता हूं और typeof(T) जैसी चीजों का उपयोग करना चाहता हूं।क्या यह इंटरफ़ेस सामान्य रूप से कार्यान्वित करना संभव है ताकि इसे केवल एक प्रकार का पैरामीटर पारित किया जा सके?

यह ठीक काम करता है:

public class ClassName<T, TId> where T : Identifiable<TId> 

समस्या है कि कोड को बुला दो प्रकार में पारित करने के लिए है। जैसे। new ClassName<Person, int>()

मुझे आश्चर्य है कि .NET 3.5 में यह लिखने का कोई तरीका है ताकि टीआईडी ​​को टी द्वारा अनुमानित किया जा सके? कॉलर को केवल new ClassName<Person>() करने की अनुमति है?

+1

शायद आप तो यह कर सकता है एक से थोड़ा अधिक वर्बोज़ उदाहरण दिखा सकता है:

public class BaseClassName<T, TId> where T: Identifiable<TId> { } public class ClassName<T> : ClassName<T, int> { } var x = new ClassName<Person>(); 

लगातार कम मामले हैं जब आप टीआईडी ​​के रूप में पूर्णांक नहीं करना चाहती के लिए, तो arity 2 वर्ग अभी भी उपलब्ध है स्पष्ट हो कि आप क्या करने की कोशिश कर रहे हैं और क्यों। – deepee1

उत्तर

2

आपके प्रश्न की प्रकृति से, मुझे लगता है कि आपका क्लासनाम पहचानने योग्य किसी भी तरीके पर भरोसा नहीं करता है जिसके लिए टीआईडी ​​की आवश्यकता होती है (अन्यथा आपको प्रकार की आवश्यकता होगी।) यदि ऐसा है, तो इस मामले में एक आम समाधान एक गैर-जेनेरिक आधार इंटरफ़ेस बनाना है, जिसमें उन सभी विधियों के साथ TId प्रकार की आवश्यकता नहीं है। तो फिर तुम है:

interface Identifiable<TId> : Identifiable //Not a standard interface name, btw 

और अपने बाधा बन जाता है:

public class ClassName<T> where T : Identifiable 

यह मानते हुए कि आप वास्तव में टीआईडी ​​प्रकार की जरूरत है, लेकिन सिर्फ, निर्माण वाक्य रचना एक विकल्प आसान बनाने के लिए, देख रहे हैं आपका कन्स्ट्रक्टर पहचानकर्ता (जैसे कि आपके उदाहरण में व्यक्ति) का एक उदाहरण ले रहा है, निर्माता को फैक्ट्री विधि में बदलना है:

public static ClassName<T, TId> FromIdentifiable<T,TId>(T identifiable) where T: Identifiable<TId> 

उपरोक्त को संकलक के प्रकार के आधार पर कंपाइलर को प्रकारों का अनुमान लगाने और आपको एक छोटा वाक्यविन्यास देने की अनुमति देनी चाहिए।

1

नहीं। आपको Identifiable<> के लिए एक प्रकार पैरामीटर प्रदान करने की आवश्यकता है; आप कैसे कर सकता है कि वर्ग घोषणा में पैरामीटर की घोषणा के बिना: where खंड के साथ

public class ClassName<T> where T : Identifiable<?WhatDoWePutHere?> 
1

AFAIK, यह संभव नहीं। आप कोड अनुबंधों का उपयोग करना चाहेंगे (उदा। नेट 4 में) और

Contract.Requires(T is Identifiable<TId>); 

अपने कोड में जोड़ें। मुझे नहीं पता कि नेट 3.5 में इसे लागू करने का कोई तरीका है या नहीं।

1

यदि आपका वर्ग के ज़्यादातर उपयोग प्रपत्र ClassName<Person, int> जहां टी प्रकार (व्यक्ति) क्या समय के सबसे भिन्न होता है लेकिन टीआईडी ​​प्रकार लगभग हमेशा int है की हो जाएगा, तो आप एक आंशिक रूप से हल वर्ग कि टीआईडी ​​की आपूर्ति प्रदान कर सकता है टाइप करें लेकिन टी प्रकार को अनबाउंड रखता है। इसका मुख्य नकारात्मक पक्ष यह है कि आपके पास कई कक्षाएं होंगी जिनके पास अलग-अलग नाम हों।

var y = new BaseClassName<Person, int>() 

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

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