2010-07-08 4 views
0

Это не работает. Является ли это возможным?Явный оператор ротации, дженерики, наследование и интерфейсы

public interface IInterface1 {} 
public interface IInterface2 { } 

public interface IMyT1 : IInterface1 {} 
public interface IMyT2 : IInterface2 {} 

public abstract class BaseClass<T1, T2> : Interface2 where T1 : IInterface1, where T2 : IInterface2 
{ 
    protected T1 T1Obj {get;set;} 

    public static explicit operator T1(BaseClass<T1,T2> val) 
    { 
      return val.T1Obj; 
    } 
} 

public class SomeClass : BaseClass<IMyT1, IMyT2>, ISomeClass {} 

Все забросы на SomeClass неудачу с InvalidCastException.

ISomeClass mySomeClass = new SomeClass(); 
var myT1 = (IMyT1)mySomeClass; //Boom! 

Это может быть сумасшедшим, но возможно ли это?

+0

Какое определение IMyT1? и IMyT2? –

ответ

2

Что вы ищете, это Общая дисперсия. По крайней мере, я так полагаю - в вашем примере кода отсутствуют биты, которые нам потребуются, чтобы проверить, действительно ли это будет .

Вы не можете использовать его вообще в C# 3 и ранее. В C# 4 вы можете использовать его для интерфейсов и делегатов, но только там, где явно помечены с помощью in и out соответственно по параметрам типа - компилятор гарантирует, что в целом это безопасно.

Если вы ищете общий вариант или ковариацию и контравариантность на этом сайте, вы найдете много информации. Или вы можете посмотреть на нем Eric Lippert's blog series. Я подробно расскажу об этом в главе 13 из C# in Depth, и если вы ищете «ковариацию» на NDC 2010 streaming video site, вы можете транслировать или скачивать часовые разговоры, которые я дал по этой теме.

+0

Dang. Я думаю, что вы ответили на общий вопрос о разнице в прошлом. Я даже не думал об этом как о проблеме, пока вы не придумали это. Я понимаю, почему это не сработает. Благодаря! –

+0

Джон, у меня есть твоя книга, C# в глубине (в MEAP, я все еще жду связанного издания), и я очень благодарен вам за это. Это расширяет мое образование на C#, как никогда раньше. – Cyberherbalist

+0

@Cyberherbalist: Я очень рад это слышать :) (Я с нетерпением жду печатной копии второго издания тоже!) –

1

Объект не является типом IMyT1, поэтому преобразование не выполняется.

Это ваши действительные преобразования ...

var instance = new SomeClass(); 
var localInterface = (ISomeClass)instance; 
var baseClass = (BaseClass<IMyT1, IMyT2>)instance; 
var baseInterface = (IInterface2)instance; 

... instance не типа IMyT1, IMyT2 или IInterface1. Попытка бросить кого-либо из них не удастся. Если BaseClass или SomeClass унаследовано от IMyT1, тогда вы сможете выполнить это преобразование.

Также статические методы разрешаются во время компиляции, в то время как литье рассматривается в RunTime. Это одна из тех же причин, почему вы не можете использовать методы virtual static.

Смежные вопросы