简体   繁体   English

带运算符的协变泛型?

[英]Covariant generics with an operator?

Is there any way to have this class's generic argument be covariant while keeping the operator? 有什么办法可以让此类的泛型参数在保持运算符的同时协变?

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

}

So that I can have, say, a ContentReference<Audio> be assigned to by a ContentReference<SoundEffect> or ContentReference<MusicTrack> ? 这样我就可以将ContentReference<Audio>分配给ContentReference<SoundEffect>ContentReference<MusicTrack>

The response is no... What you can do: 响应为否。您可以做什么:

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 
    }
}

So the solution is that you can have a base class (optionally abstract ) that exposes the common methods that are partially implemented in the base class and partially implemented in the subclass(es). 因此,解决方案是您可以拥有一个基类(可选为abstract ),该基类公开一些在基类中部分实现且在子类中部分实现的通用方法。

Or you could define a contravariant IContentReference<out T> : 或者,您可以定义一个反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);
    }
}

and then: 接着:

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());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM