代码之家  ›  专栏  ›  技术社区  ›  Josh Russo

使用C#泛型扩展?

  •  4
  • Josh Russo  · 技术社区  · 15 年前

    我希望能够从GroupType和/或OptionType创建子类。问题是我不能执行 new 对泛型类型的操作,即使我指定它们只能是某个基类型。

    有什么办法做我想做的吗?

    public class AllInfo<GroupType, OptionType> 
        where GroupType: GroupBase<OptionType>
        where OptionType: OptionBase
    {
        public List<string> Names { set; get; }
        public List<GroupType> Groups { set; get; }
    
        public AllInfo()
        {
            DataSet ds = DatabaseRetreival();
            this.Groups.add(new GroupType(ds["Name"], ds["Type"]));
        }
    
    }
    
    public class GroupBase<OptionType> 
        where OptionType: OptionBase
    {
        public string Name { set; get; }
        public string Type { set; get; }
        public List<OptionType> Options { set; get; }
    
        public GroupBase(string name, string type)
        {
             this.Name = name;
             this.Type = type;
    
             DataSet ds = DatabaseRetreival(this.Type);
             this.Options.Add(new OptionType(ds["Name"]));
        }
    }
    
    public class OptionBase
    {
        public string Name { set; get; }
    
        public OptionBase(string name)
        {
            this.Name = name;
        }
    }
    
    4 回复  |  直到 15 年前
        1
  •  2
  •   Guffa    15 年前

    不能指定泛型类应该具有哪些构造函数。构造函数不是继承的,因此即使您指定的基类具有该构造函数,从其派生的类也不必具有该构造函数。

    您唯一需要的构造函数是无参数构造函数:

    where GroupType: GroupBase<OptionType>, new()
    

    GroupType group = new GroupType();
    group.Init(ds["Name"], ds["Type"]);
    this.Groups.add(group);
    
        2
  •  4
  •   Erik Noren    15 年前

    必须指定类必须具有默认构造函数。

    where GroupType: GroupBase<OptionType>, new()
    

    查看 this article 一般约束 .

        3
  •  1
  •   Wim Coenen    15 年前

    编译器不能允许这样做,因为它不能保证 OptionType 具有具有正确签名的构造函数。但您可以传递工厂函数,而不是直接调用构造函数:

    public class Foo<T> 
    {
        private List<T> myObjects;
    
        public Foo(Func<string, T> factory))
        {
            myObjects = new List<T>();
            foreach (string s in GetDataStrings())
                myObjects.Add(factory(s));
        }
    }
    

    Bar 使用构造函数获取字符串初始化,可以执行以下操作:

    Func<string,Bar> barFactory = x => new Bar(x);
    var foo = new Foo<Bar>(barFactory);
    
        4
  •  0
  •   Squirrelsama    14 年前

    你的问题是基于大量的类耦合的基础上,你试图用继承/泛型来减轻。我建议你重新审视一下为什么你觉得这是必要的。这个任务最终会引导你找到接口,基于服务的编程,以及Ninject或Castle Windsor之类的ioc。

    使用抽象/虚拟方法 ,或者称之为Bind(),

    [粗体表示tl;dr]