【问题标题】:Covariant generics with an operator?带有运算符的协变泛型?
【发布时间】:2015-05-18 16:34:28
【问题描述】:

有没有办法让这个类的泛型参数在保持操作符的同时保持协变?

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&lt;Audio&gt; 分配给ContentReference&lt;SoundEffect&gt;ContentReference&lt;MusicTrack&gt;

【问题讨论】:

  • 因为只有接口(和委托)可以是协变的,所以答案是否定的。或许,如果您详细说明您想要做什么(以及为什么_可以提供替代方案。
  • 关于@DStanley 写的内容,我要补充一点:只有接口可以是协变/逆变的。只有类/结构可以有运算符(因为它们是静态方法)
  • 哎呀,按错了按钮。我会澄清我的确切情况。
  • @xanatos 我已经纠正了。评论已删除。
  • @AlphaMCubed 响应仍然没有 :-) 你可以创建一个基本的 ContentReference 类,并有一些 virtual 方法

标签: c# operator-overloading covariance


【解决方案1】:

回答是否定的……你可以做什么:

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&lt;out T&gt;

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-01
    • 1970-01-01
    • 2010-12-19
    • 2014-10-07
    • 1970-01-01
    • 1970-01-01
    • 2016-06-10
    • 1970-01-01
    相关资源
    最近更新 更多