在接口中使用泛型

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

编辑 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);
8个回答

7

看起来你有3个选项:

1. 使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);
}

1

我认为你想要的是:

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

目前ICookieService2不是泛型,因此T未定义。

这使您可以创建实现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。如果您需要从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

你可以尝试一下

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

这样,所有T的实例都将被强制具有Object的基类型。(在C#中几乎所有东西都是如此,例如int == System.Integer等)。


0

不确定C#的情况,但Java的方式是还要声明你的ICookieService2有一个<T>参数,或者在CookieData中将<T>指定为具体的内容。


0
如果我正确理解您的问题,您想要将通用类型视为相同,但在当前的.NET实现中,您无法这样做。
CookieData<string>不能作为CookieData<int>传递,它们实际上是不同的类型,通用类型之间没有关系,不能像相同的类型一样进行转换或传递。将ICookieService2创建为开放式通用类型(即ICookieService2<T>)无法解决问题,因为那么您将为每种不同类型创建一个不同的ICookieService2类型,并且所有这些类型都将在不同的字典中。
您可以创建一个ICookieData接口,并在CookieData<T>中实现它,并使用ICookieData将项目存储在字典中(正如Stefan已经建议的那样)。
你可以在C# 4.0中做你想做的事情(有一些限制)。这里有一篇文章 在这里,在那之前,你必须将它作为一个通用类型传递,比如一个接口,或者只是将值参数作为字典上的对象,因为如果使用原语作为类型参数,你仍然需要转换它才能使用它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接