C#通用列表

时间:2009-02-18 21:49:58

标签: c# generics

我有一个映射到数据库中字段的类。该类仅关注字段的名称及其相关的.NET类型。 类型可以是字符串,整数,日期时间等

class Foo()
{
    string Name { get; set; }
    Type FooType { get; set; }
}

我有另一个继承自Foo的类,它为值添加了一个属性。现在我将值存储为对象,并使用switch语句根据基类FooType对值进行装箱。

class FooWithStuff() : Foo
{
    object Value { get; set; }   
}

有没有办法用泛型实现这个来为值赋予类型安全性?

修改:我已将关键要求设为粗体。在声明列表时说Foo需要一个类型。如果我对自定义类这样做,我会创建和接口并使用它。但是在这里我使用int,string,DateTime等.Int是一个结构,字符串是一个对象,所以一个Foo<对象>对两者都不起作用。

6 个答案:

答案 0 :(得分:9)

class Foo
{
    public string Name { get; set; }
    public Type Type { get; set; }
}

class Bar<T> : Foo
{
    public T Value { get; set; }

    public Bar()
    {
        base.Type = typeof( T );
    }
}

答案 1 :(得分:8)

像这样定义你的类:

class Foo<T> : IFoo
{

    public Foo(string name)
    {
        Name = name;
    }

    string Name { get; set; }
    T Value {get; set;}
    Type FooType { get { return typeof(T); } }
}

然后,您可以将接口IFoo定义为:

string Name { get; set; }
Type FooType { get; set; }

并将列表声明为:

List<IFoo> list = new List<IFoo>();

答案 2 :(得分:2)

如果你想为Foo添加Value并让Foo成为通用的你可以做...

class Foo<T>
{
    T Value {get; set;}
}

Foo<int> myFoo = new Foo<int>();
myFoo.Value = 7;

答案 3 :(得分:1)

我会使用接口而不是泛型类继承。

编辑:澄清。我会使用Interface for Foo,以及FooWithStuff的泛型类:

public interface IFoo
{
  string Name{get;set;}
  Type FooType{get;set;}
}

public class FooWithStuff<T>:IFoo
{
   T Value {get;set;}
}

答案 4 :(得分:0)

是的,实际上你可以取消你的继承,只是..

public class Foo<T>
{
  public string Name {get;set;}
  public T Value {get;set;}
  public Type FooType
  {
     get
     {
       return typeof(T);
     }
  }
}

另请注意,使用linq,您可以直接从列表中提取所需的类型,因此如果您只是因为某种原因对字符串字段感兴趣,那么可以...

List<object> list = getAllmyFoos();
foreach(Foo<string> sfoo in list.OfType<Foo<string>>())
{
  ...blah
}

编辑:添加了FooType。

答案 5 :(得分:-2)

我会使用2个接口重新编写:

public interface IFoo
{
  string Name {get; }
  Type Type { get; }
  object Value {get; set;}
}

public interface IFoo<T> : IFoo
{
  T Value {get; set}
}

然后实施它:

public class Foo<T> : IFoo<T>
{
   private T value;
   public Foo(string name, T value)
   {
     this.name = name;
     this.value = value;
   }

   public string Name { get { return name; } }
   public Type Type { get { return typeof(T); } }
   public T Value
   {
      get { return value; }
      set { value = value; }
   }

   object IFoo.Value
   {
      get { return value; }
      set { value = (T)value; }  // can check type before
   }
}

这样,您也可以在非通用上下文中轻松使用IFoo接口。