代码之家  ›  专栏  ›  技术社区  ›  blu

C通用列表

  •  3
  • blu  · 技术社区  · 16 年前

    我有一个类,它映射到数据库中的一个字段。类只关心字段的名称及其相关的.NET类型。 类型可以是string、int、datetime等。

    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是一个结构,string是一个对象,因此foo<object>对这两者都不起作用。

    6 回复  |  直到 16 年前
        1
  •  8
  •   Lars Mæhlum    16 年前

    这样定义类:

    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
  •  9
  •   xian    16 年前
    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 );
        }
    }
    
        3
  •  2
  •   Quintin Robinson    16 年前

    如果你想给foo增加值,让foo是通用的,你可以这样做…

    class Foo<T>
    {
        T Value {get; set;}
    }
    
    Foo<int> myFoo = new Foo<int>();
    myFoo.Value = 7;
    
        4
  •  1
  •   Mike_G    16 年前

    我将在上面使用接口而不是通用类继承。

    编辑:澄清。我将为foo使用一个接口,为foowithstufacture使用一个通用类:

    public interface IFoo
    {
      string Name{get;set;}
      Type FooType{get;set;}
    }
    
    public class FooWithStuff<T>:IFoo
    {
       T Value {get;set;}
    }
    
        5
  •  0
  •   Tim Jarvis    16 年前

    是的,事实上,你可以简单地放弃你的遗产……

    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。

        6
  •  -2
  •   thinkbeforecoding    16 年前

    我将使用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接口。