2015-05-18 3 views
0

Есть ли способ, чтобы общий аргумент этого класса был ковариантным при сохранении оператора?Ковариантные дженерики с оператором?

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

+2

Поскольку только интерфейсы (и делегаты) могут быть ковариантны, ответ нет. Возможно, если вы объясните больше того, что вы делаете _wanting_ (и почему: может быть предоставлена ​​альтернатива. –

+0

В том, что написал @DStanley, я добавлю: только интерфейсы могут быть ковариантными/контравариантными. Только классы/структуры могут иметь операторы (потому что они являются статическими методами) – xanatos

+0

Убивает неправильную кнопку. Я уточню свою точную ситуацию. – AlphaModder

ответ

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()); 
Смежные вопросы