2009-06-01 2 views
5

Как разрешить мой CookieData быть общим в следующем коде? Я получаю ошибку времени компиляции в объявлении ICookieService2.Использование дженериков в интерфейсах

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

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

Моя ошибка:

Тип или пространство имен имя «T» не может быть найден (вы пропали без вести с помощью директивы или ссылка на сборку?)

Я желая, чтобы ICookieService2 вводил в него общие данные. Благодаря!

Редактировать Не запереть меня в один T для строительства любых ICookieService2?

Edit 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> { 
... 
} 

Создать необщую базу класса для CookieData и использовать его в интерфейсе

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

не уверен о C#, но Java-способ должен был бы также объявить лет ur ICookieService2, чтобы иметь параметр <T>, или указать <T> на что-то конкретное в CookieData.

+0

ОК, видя из ответов выше, это правильно :) – Jorn

1

Я думаю, что вы хотите:

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

В настоящее время ICookieService2 не является универсальным, поэтому T не определен.

Это позволяет создавать классы орудие ICookieService2<string> или ICookieService2<int> и т.д.

EDIT: В ответ на вашу последнюю просьбу, я думаю, что это действительно зависит от того, что именно это вам нужно. Однако что-то вроде этого может сработать для вас.

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. Если вам нужно написать (установить) из CookieService, это немного сложнее и, возможно, лучше не использовать дженерики. Но если вам просто нужно получить 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

Если я правильно понимаю ваш вопрос вы хотели лечить общие типы, как они одинаковы, но в текущей реализации .NET вы не можете сделать это.

< CookieData строка > не может быть передана как CookieData <Int> они на самом деле разные типы, общие типы не связаны и не могут быть поданы или переданы как они одинаковы. Создание ICookieService2 как открытого родового (то есть ICookieService2 <T>) не решает проблему, потому что тогда у вас будет другой тип ICookieService2 для каждого другого типа, и все они будут в другом словаре.

Вы можете создать интерфейс ICookieData и реализовать его в CookieData <T> и использовать ICookieData для хранения элементов в словаре (как уже указывал Стефан).

Вы можете делать то, что хотите в C# 4.0 (с некоторыми ограничениями). Есть статья об этом here до тех пор, вы должны передать ее как не общий тип, который является общим для них, такой как интерфейс, или просто иметь параметр значения как объект в словаре, потому что вам придется иметь дело его использовать в любом случае, если вы используете примитивы в качестве аргументов типа.

0

Вы можете попробовать

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

Таким образом, все экземпляры Т будут вынуждены иметь базовый тип объекта. (почти все в C# (например, int == System.Integer и т. д.)

Смежные вопросы