泛型类属性

时间:2015-09-30 05:26:26

标签: c# wpf generics

我有以下课程:

BaseField:

public abstract class BaseField {
    ...
    public BaseField()
    {

    }

    public BaseField(E_FieldType fieldType)
    {
        _FieldType = fieldType;
    }
}

的TextField:

public class TextField : BaseField {
    ...
    public TextField() : base(E_FieldType.Text)
    {

    }
}

的DateField:

public class DateField : BaseField {
    ...
    public DateField() : base(E_FieldType.Date)
    {

    }
}

DataBlock 类应包含 TextField DateField

public class DataBlock<T> : BaseBlock where T : BaseField, new() {
    ...
    private T _Field;
    public DataBlock(string name): base(name, E_BlockType.Data) 
    {
        _Field = new T();            
    }
}

以下行正常:

DataBlock<TextField> db = new DataBlock<TextField>("qwe");

但是无法编写此代码:

public ObservableCollection<DataBlock<BaseField>> DataBlockList { get; set; }

public DataBlockViewModel()
{
    DataBlockList = new ObservableCollection<DataBlock<BaseField>>();
    DataBlockList.Add(new DataBlock<TextField>("qwe"));
    DataBlockList.Add(new DataBlock<DateField>("asd"));
}

错误是:

  

&#39; BaseField&#39;必须是具有公共无参数的非抽象类型   构造函数,以便将其用作参数&#39; T&#39;在通用类型或   方法'DataBlock<T>'

请问您如何解决我可以创建ObservableCollection<DataBlock<BaseField>>集合的问题?

我可以从new()

中删除public class DataBlock<T> : BaseBlock where T : BaseField
public DataBlock(string name): base(name, E_BlockType.Data) 
{
    //_Field = new T();            
}

在这种情况下,我可以创建DataBlockList = new ObservableCollection<DataBlock<BaseField>>();

但是不可能写:

DataBlockList.Add(new DataBlock<TextField>("qwe"));
DataBlockList.Add(new DataBlock<DateField>("asd"));

1 个答案:

答案 0 :(得分:1)

有两种方法可以消除错误:

1)您可以使班级BaseField非抽象

public abstract class BaseField {
    ...
    public BaseField()
    {

    }

    public BaseField(E_FieldType fieldType)
    {
        _FieldType = fieldType;
    }
}

2)将新的BaseField对象作为构造函数参数传递给DataBlock并删除new()约束。

public class DataBlock<T> : BaseBlock where T : BaseField {
    ...
    private T _Field;
    public DataBlock(string name, T field): base(name, E_BlockType.Data) 
    {
        _Field = field;            
    }
}