2009-06-01 22 views
5

¿Cómo permito que mi CookieData sea genérico en el siguiente código? Aparece un error de tiempo de compilación en la declaración de ICookieService2.Uso de genéricos en interfaces

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

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

Mi error es:

El tipo o espacio de nombres 'T' no se pudo encontrar (¿falta una directiva using o una referencia de ensamblado?)

soy queriendo ICookieService2 tener datos genéricos insertados en él. ¡Gracias!

Editar ¿Eso no me encerrará en un solo T para la construcción de cualquier ICookieService2?

Editar 2 Lo que estoy tratando de hacer es la siguiente:

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

Respuesta

7

Parece que usted tiene 3 opciones aquí

Hacer ICookieService2 genérica

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

crear una base no genérico clase para CookieData y usar eso en la interfaz

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

Escoja una implementación concreta

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

usted debe hacer ICookieService2 genérica así:

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

OK, aquí es lo que quiere:

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

no estoy seguro acerca de C#, pero la forma de Java sería declarar también yo ur ICookieService2 para tener el parámetro <T>, o para especificar el <T> a algo concreto en CookieData.

+0

bien, viendo desde arriba las respuestas es correcto :) – Jorn

1

Creo que lo que desea es:

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

Actualmente ICookieService2 no es genérico, por lo que T no está definido.

Esto le permite crear clases de la aplicación de ICookieService2<string> o ICookieService2<int>, etc.

EDIT: En respuesta a su solicitud más reciente, creo que realmente depende de qué es exactamente lo que necesita. Sin embargo, algo como esto puede funcionar para usted.

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

Entonces CookieService puede ser o tener una lista y que sería capaz de añadir tanto CookieData y CookieData. Si necesita escribir (establecer) desde CookieService, es un poco más complicado y posiblemente mejor no usar genéricos. Pero si solo necesita poder recuperar el CookieData, entonces esto podría funcionar para usted.

1

Se necesita un interfaz no genérico para hacer esto:

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

Si entiendo bien su pregunta usted está deseando para tratar los tipos genéricos como son el mismo, pero en la actual aplicación .NET no se puede hacer esto.

CookieData <cadena> no se puede pasar como un CookieData <int> en realidad son diferentes tipos, los tipos genéricos no están relacionados y no puede ser fundido o se pasa como si son los mismos. La creación de ICookieService2 como un genérico abierto (es decir, ICookieService2 <T>) no resuelve el problema porque entonces usted tendría un tipo diferente de ICookieService2 para cada tipo diferente y todos ellos estarían en un diccionario diferente.

Puede crear una interfaz ICookieData e implementarla en CookieData <T> y usar ICookieData para almacenar los elementos en el diccionario (como Stefan ya ha sugerido).

Puede hacer lo que quiera en C# 4.0 (con algunas restricciones). Hay un artículo al respecto here hasta entonces, tienes que pasarlo como un tipo no genérico que es común para ellos, como una interfaz o simplemente tener el parámetro de valor ser un objeto en el diccionario porque vas a tener que presentar un caso usarlo de todos modos si está utilizando primitivas como argumentos de tipo.

0

Usted podría intentar

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

De esta manera todas las instancias de T se vería obligado a tener un tipo base del objeto. (prácticamente todo en C# (por ejemplo, int == System.Integer, etc.)

Cuestiones relacionadas