2009-06-01 18 views
5

मैं निम्नलिखित कोड में सामान्य होने के लिए अपने CookieData को कैसे अनुमति दूं? मुझे ICookieService2 की घोषणा पर संकलन-समय त्रुटि मिलती है।इंटरफेस में जेनिक्स का उपयोग

public struct CookieData<T> 
{ 
    T Value { get; set; } 
    DateTime Expires { get; set; } 
} 

public interface ICookieService2: IDictionary<string, CookieData<T>> 
{ 
    // ... 
} 

मेरे त्रुटि है:

प्रकार या नाम स्थान नाम 'टी' नहीं पाया जा सका (यदि आप एक का उपयोग कर के निर्देश या एक विधानसभा संदर्भ याद कर रहे हैं?)

मैं कर रहा हूँ ICookieService2 चाहते हैं कि इसमें सामान्य डेटा डाला जाए। धन्यवाद!

संपादित मुझे एक भी T किसी भी ICookieService2 के निर्माण के लिए में ताला कि नहीं होगा?

संपादित 2 मुझे क्या करना कोशिश कर रहा हूँ पीछा कर रहा है:

CookieData<int> intCookie = { Value = 27, Expires = DateTime.Now }; 
CookieData<string> stringCookie = { Value = "Bob", Expires = DateTime.Now }; 

CookieService2 cs = new CookieService2(); 
cs.Add(intCookie); 
cs.Add(stringCookie); 

उत्तर

7

ऐसा लगता है कि आप 3 विकल्प यहाँ

है ICookieService2 सामान्य

public interface ICookieService2<T> : IDictionary<string, CookieData<T> { 
... 
} 

एक गैर सामान्य आधार बनाएं बनाओ कुकीडाटा के लिए कक्षा और इंटरफेस में इसका उपयोग करें

public interface ICookieData {} 
public class CookieData<T>: ICookieData{} 
public interface ICookieService2 : IDictionary<string, ICookieData> {} 

एक ठोस कार्यान्वयन

public interface ICookieService : IDictionary<string, CookieData<int>> {} 
4

आप ICookieService2 सामान्य रूप में अच्छी तरह बनाना चाहिए:

public interface ICookieService2<T>: IDictionary<string, CookieData<T>> 
{ 
    // ... 
} 
2

ठीक है, यहाँ तुम क्या चाहते हो:

public interface ICookieDataBase 
{ 
    DateTime Expires { get; set; } 
} 

public struct CookieData<T> : ICookieDataBase 
{ 
    public T Value { get; set; } 
    public DateTime Expires { get; set; } 
} 

public class ICookieService : IDictionary<string, ICookieDataBase> 
{ 
    // ... 
} 

public void DoWork() 
{ 
    var intCookie = 
     new CookieData<int> { Value = 27, Expires = DateTime.Now }; 

    var stringCookie = 
     new CookieData<string> { Value = "Bob", Expires = DateTime.Now }; 

    ICookieService cs = GetICookieService(); 
    cs.Add(intCookie); 
    cs.Add(stringCookie); 
} 
0

सी # के बारे में निश्चित नहीं है, लेकिन जावा तरीका भी आपको घोषित करना होगा ICookieService2<T> पैरामीटर के लिए, या CookieData में कुछ ठोस के लिए <T> निर्दिष्ट करने के लिए।

+0

ठीक है, ऊपर दिए गए उत्तरों से यह सही है :) – Jorn

1

मुझे लगता है कि क्या आप चाहते हैं:

public interface ICookieService2<T>: IDictionary<string, CookieData<T>> 
{ 
    // ... 
} 

वर्तमान में ICookieService2 नहीं सामान्य है, तो टी परिभाषित नहीं है। अपने नवीनतम अनुरोध के जवाब में मुझे लगता है कि यह वास्तव में यह वास्तव में क्या आप की जरूरत है पर निर्भर करता है:

यह लागू ICookieService2<string> या ICookieService2<int>, आदि

संपादित करें आप कक्षाएं बनाने के लिए अनुमति देता है। हालांकि, ऐसा कुछ आपके लिए काम कर सकता है।

public interface ICookieData 
{ 
    object Value {get;} // if you need to be able to set from CookieService, life gets harder, but still doable. 
    DateTime Expires {get;} 
} 

public struct CookieDate<T> : ICookieData 
{ 
    T Value {get;set;} 
    DateTime Expires {get;set;} 

    object ICookieData.Value 
    { 
     get 
     { 
      return Value; 
     } 
    } 
} 

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

1

आप एक गैर सामान्य इंटरफेस की जरूरत है ऐसा करने के लिए:

public interface ICookieData 
{ 
    // you need this to get the value without knowing it's type 
    object UntypedValue { get; } 
    // whatever you need additionally ... 
    Type DataType { get; } 

    DateTime Expires { get; set; } 
} 

public struct CookieData<T> : ICookieData 
{ 
    // ICookieData implementation 
    public object UntypedValue { get { return Value; } } 
    public Type DataType { get { return typeof(T); } } 
    public DateTime Expires { get; set; } 

    // generic implementation 
    T Value { get; set; } 
} 

public interface ICookieService2: IDictionary<string, ICookieData> 
{ 
    // ... 
} 

CookieData<int> intCookie = { Value = 27, Expires = DateTime.Now }; 
CookieData<string> stringCookie = { Value = "Bob", Expires = DateTime.Now }; 

CookieService2 cs = new CookieService2(); 
cs.Add(intCookie); 
cs.Add(stringCookie); 
0

उठाओ अगर मैं अपने प्रश्न समझ में सही ढंग से आप सामान्य प्रकार के इलाज के लिए इच्छुक रहे हैं जैसे वे एक ही हैं, लेकिन मौजूदा नेट कार्यान्वयन में यदि आप ऐसा नहीं कर सकते हैं।

CookieData < स्ट्रिंग > वे वास्तव में विभिन्न प्रकार हैं एक CookieData < पूर्णांक > के रूप में पारित नहीं किया जा सकता, सामान्य प्रकार से संबंधित नहीं हैं और ढाला नहीं जा सकता या पारित कर दिया है कि वे एक ही हैं। ICookieService2 को एक खुले जेनेरिक के रूप में बनाना (जिसका अर्थ है ICookieService2 < टी >) समस्या का समाधान नहीं करता है क्योंकि तब आपके पास प्रत्येक अलग-अलग प्रकार के लिए एक अलग ICookieService2 प्रकार होगा और उनमें से सभी एक अलग शब्दकोश में होंगे।

आप एक ICookieData इंटरफ़ेस बनाने और CookieData < टी > में इसे लागू और शब्दकोश में आइटम संग्रहीत करने के लिए (के रूप में स्टीफन पहले से ही सुझाव दिया है) ICookieData उपयोग कर सकते हैं।

आप सी # 4.0 (कुछ प्रतिबंधों के साथ) में जो भी चाहते हैं वह कर सकते हैं। इसके बाद here के बारे में एक लेख है, आपको इसे एक गैर-जेनेरिक प्रकार के रूप में पास करना होगा जो उनके लिए आम है जैसे इंटरफ़ेस या केवल मान पैरामीटर शब्दकोश पर एक ऑब्जेक्ट है क्योंकि आपको केस होना होगा यदि आप प्राइमेटिव्स को टाइप तर्क के रूप में उपयोग कर रहे हैं तो इसे इसका उपयोग करने के लिए।

0

आप

public struct CookieData<T> 
    where T : Object 
{ 
    T Value { get; set; } 
    DateTime Expires { get; set; } 
} 

इस तरह टी के सभी उदाहरणों वस्तु का आधार प्रकार है करने के लिए मजबूर किया जाएगा की कोशिश कर सकते। (सी # में बहुत कुछ सब कुछ (उदा। int == System.Integer इत्यादि)

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