2009-06-01 20 views
5

Come posso consentire al mio CookieData di essere generico nel seguente codice? Ricevo un errore in fase di compilazione sulla dichiarazione di ICookieService2.Utilizzo di generici nelle interfacce

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

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

Il mio errore è:

Il nome tipo o dello spazio dei nomi 'T' non è stato trovato (che le manca un un riferimento all'assembly direttiva using o?)

Sono volendo ICookieService2 per inserire dati generici in esso. Grazie!

Modifica Non sarà che mi blocca in un unico T per la costruzione di qualsiasi ICookieService2?

Edit 2 Quello che sto cercando di fare è il seguente:

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); 

risposta

7

Sembra che tu hai 3 opzioni qui

Fai ICookieService2 generico

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

creare una base non generico classe per CookieData e utilizzare quella nell'interfaccia

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

Scegli una concreta attuazione

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

È necessario rendere ICookieService2 generico così:

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

OK, qui è quello che vuoi:

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

non sono sicuro di C#, ma il modo Java sarebbe anche dichiarare yo ur ICookieService2 per avere il parametro <T> o per specificare lo <T> su qualcosa di concreto in CookieData.

+0

ok, vedere da sopra le risposte questo è corretto :) – Jorn

1

penso che quello che vuoi è:

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

attualmente ICookieService2 non è generica, in modo da T non è definito.

Questo consente di creare classi l'attrezzo ICookieService2<string> o ICookieService2<int>, ecc

EDIT: In risposta alla vostra ultima richiesta, penso che in realtà dipende esattamente quello che è necessario. Tuttavia, qualcosa di simile potrebbe funzionare per te.

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; 
     } 
    } 
} 

Poi CookieService possono essere o avere una lista e si sarebbe in grado di aggiungere sia CookieData e CookieData. Se devi scrivere (set) da CookieService, è un po 'più complicato, e forse meglio non usare i generici. Ma se hai solo bisogno di essere in grado di recuperare i CookieData, allora questo potrebbe funzionare per te.

1

Hai bisogno di un interfaccia non generica per fare questo:

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

Se ho capito la sua domanda si vogliono trattare i tipi generici come se fossero la stessa cosa, ma in attuale implementazione .NET non si può fare questo.

CookieData <stringa> non può essere passato come CookieData <int> realtà sono diversi tipi, i tipi generici non sono correlate e non possono essere lanciato o passò come sono gli stessi. La creazione di ICookieService2 come un generico aperto (ovvero ICookieService2 <T>) non risolve il problema, poiché in questo caso si avrebbe un diverso tipo ICookieService2 per ogni tipo diverso e tutti sarebbero in un dizionario diverso.

È possibile creare un'interfaccia ICookieData e implementarla in CookieData <T> e utilizzare ICookieData per memorizzare gli elementi nel dizionario (come già suggerito da Stefan).

È possibile eseguire ciò che si desidera in C# 4.0 (con alcune limitazioni). C'è un articolo su di esso here fino ad allora, devi passarlo come un tipo non generico che è comune a loro come un'interfaccia o semplicemente avere il parametro value essere un oggetto sul dizionario perché devi fare il caso per usarlo comunque se si usano le primitive come argomenti del tipo.

0

Si potrebbe provare

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

In questo modo tutte le istanze di T sarebbero costretti ad avere un tipo di base di oggetto. (praticamente tutto in C# (ad es. int == System.Integer ecc.)

Problemi correlati