与运算符一致的协变泛型?

时间:2015-05-18 16:34:28

标签: c# operator-overloading covariance

有没有办法让这个类的通用参数在保持运算符的同时具有协变性?

public class ContentReference<T> where T : IReferable
{

    public string Name { get; private set; }

    public ContentReference(T value)
    {
        this.Name = value.Name;
    }        

    public static implicit operator ContentReference<T>(T value)
    {
        return new ContentReference<T>(value);
    }

}

因此,我可以ContentReference<Audio>ContentReference<SoundEffect>分配ContentReference<MusicTrack>

1 个答案:

答案 0 :(得分:0)

答案是否定的......你能做什么:

public abstract class ContentReference
{
    public string Name { get; private set; }

    protected ContentReference(string name)
    {
        Name = name;
    }

    public abstract void Play();
}

public class ContentReference<T> where T : IReferable
{
    public ContentReference(T value) : base(value.Name)
    {
    }        

    public static implicit operator ContentReference<T>(T value)
    {
        return new ContentReference<T>(value);
    }

    public override void Play()
    {
        // Play the IReference 
    }
}

因此,解决方案是您可以拥有一个基类(可选abstract),该基类公开部分在基类中实现并部分在子类中实现的公共方法。

或者您可以定义逆变IContentReference<out T>

public interface IContentReference<out T> where T : IReferable
{
    string Name { get; }
}

public class ContentReference<T> : IContentReference<T> where T : IReferable
{
    public string Name { get; private set; }

    public ContentReference(T value)
    {
        this.Name = value.Name;
    }

    public static implicit operator ContentReference<T>(T value)
    {
        return new ContentReference<T>(value);
    }
}

然后:

IContentReference<Audio> interf1 = new ContentReference<SoundEffect>(new SoundEffect());
IContentReference<Audio> interf2 = new ContentReference<MusicTrack>(new MusicTrack());

IContentReference<Audio> interf3 = (ContentReference<SoundEffect>)new SoundEffect();
IContentReference<Audio> interf4 = (ContentReference<MusicTrack>)(new MusicTrack());