ztsv
ztsv

Reputation: 880

generic type of class property

I have the following classes:

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)
    {

    }
}

And DataBlock class which should contain TextField or 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();            
    }
}

The following line works fine:

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

But It is not possible to write this code:

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"));
}

The error is:

'BaseField' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'DataBlock<T>'

Could you please advise how to solve the issue that I can create ObservableCollection<DataBlock<BaseField>> collection?

I can remove new() from public class DataBlock<T> : BaseBlock where T : BaseField and

public DataBlock(string name): base(name, E_BlockType.Data) 
{
    //_Field = new T();            
}

In this case I can create DataBlockList = new ObservableCollection<DataBlock<BaseField>>();

but it is not possible to write:

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

Upvotes: 0

Views: 67

Answers (1)

Domysee
Domysee

Reputation: 12846

There are 2 ways to get rid of the error:

1) You can make the class BaseField non-abstract

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

    }

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

2) Pass the new BaseField object as constructor parameter to DataBlock and remove the new() constraint.

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

Upvotes: 1

Related Questions