Nie sądzę, że tytuł może wyjaśnić, o co mi chodzi, i jest to nieco trudne do wyjaśnienia, więc pozwolę, aby kod mówił. Możesz skopiować i wkleić to do LINQPada i uruchomić jako program C# lub wprowadzić niezbędne korekty jako zwykły projekt C# w wizualnym studio (np. Zmienić wywołanie na Dump() na Console.Writeline() itp.) -Obiekt ogólny wymaga rzutowania, mimo że implementuje wymagany interfejs.
Należy zauważyć, że jeśli odkomentujesz linię w metodzie DoStuff, nie zostanie ona skompilowana.
Moje pytanie brzmi: dlaczego potrzebuję rzutowania, gdy generic2 już implementuje Iab<TA,TB>
? Czy to jest coś z kowariancji? Nadal jestem na .NET 3.5.
void Main()
{
doStuff<a,b>();
}
public void doStuff<TA, TB>()
where TA : class, Ia, new()
where TB : class, Ib, new()
{
Iab<TA, TB> x = null;
x = new generic1<TA, TB>();
x.Go().Dump();
//x = new generic2<TA>(); // <-Cannot implicitly convert type 'UserQuery.generic2<TA>' to 'UserQuery.Iab<TA,TB>'. An explicit conversion exists (are you missing a cast?)
x = (Iab<TA, TB>) new generic2<TA>();
x.Go().Dump();
}
public interface Ia
{}
public interface Ib
{}
public class a : Ia
{}
public class b : Ib
{}
public interface Iab<TA,TB>
where TA : class, Ia, new()
where TB : class, Ib, new()
{
string Go();
}
public class generic1<TA, TB> : Iab<TA,TB>
where TA : class, Ia, new()
where TB : class, Ib, new()
{
public string Go()
{
return "generic Base called";
}
}
public class generic2<TA> : Iab<TA,b>
where TA : class, Ia, new()
{
public string Go()
{
return "generic Sub called";
}
}
Ah, tak, oczywiście. Tęsknię za tym :) Dzięki! –