Изменить возврат подписи с помощью наследования - Полиморфизм - PullRequest
1 голос
/ 06 ноября 2008

Просто интересно, есть ли способ сделать следующее:

public Interface IDataField 
{
    object GetValue();
}

public Interface IComplexDataField : IDataField
{
    object GetDefaultValue();
}

public class MyBase
{
    private IDataField _DataField;

    public MyBase()
    {
        this._DataField = this.CreateDataField();
    }

    public virtual IDataField CreateDataField()
    {
        return new DataField(); //Implements IDataField 
    }

    **public virtual IDataField GetDataField()**
    {
        return this._DataField;
    }

    public void SomeMethod()
    {
        this.GetDataField().GetValue();
    }
}


public class MyComplexBase : MyBase
{
    public override IDataField CreateDataField()
    {
        return new ComplexDataField(); //Implements IComplexDataField which Implements IDataField 
    }

    **public override IComplexDataField GetDataField()**
    {
        return (IComplexDataField)base.GetDataField();
    }

    public void SomeComplexSpecificMethod()
    {
        this.GetDataField().GetValue();
        this.GetDataField().GetDefaultValue();
    }
}

Приветствие Anthony

Ответы [ 3 ]

4 голосов
/ 06 ноября 2008

То, что вы хотите, это ковариация типов возврата . Этого не существует в C #.

Не могли бы вы сделать MyBase универсальный:

public class MyBase<T> where T : IDataField
{
    public virtual T CreateDataField()
    {
        ... etc ...
    }
}

Кроме того, вы можете переопределить метод с помощью «new» и скрыть метод базового класса. Ни один из них не особенно привлекателен ...

1 голос
/ 06 ноября 2008

Самое близкое, что вы можете получить в C # 3.0, - это иметь отдельный метод virtual (например, ваш метод CreateDataField), который выполняет реальную работу и может быть переопределен, затем используйте new, чтобы повторно объявить открытый метод. , т.е. в базе:

public IDataField GetDataField()
{
    return GetDataFieldImpl();
}
protected virtual IDataField GetDataFieldImpl()
{
    // return a basic version
}

и в подклассе:

protected override IDataField GetDataFieldImpl()
{
    // do something more fun
}
public new IComplexDataField GetDataField()
{
    return (IComplexDataField)GetDataFieldImpl();
}
0 голосов
/ 06 ноября 2008

То, что вы пытаетесь сделать, называется ковариантными типами возврата. Они не существуют в текущей версии C #, но есть разговоры о том, что они будут введены для следующей версии.

Ваш лучший подход объяснен здесь: ковариантные типы возврата

public class MyBase<T> where T : IDataField, new()
{
    public virtual T CreateDataField()
    {
        return new T();
    }

    public virtual T GetDataField()
    {
        return this._DataField;
    }

}

public class MyComplexBase : MyBase<ComplexDataField>
{
   ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...