我有这个所需的类层次结构:
interface IClass
{
string print(IClass item);
}
class MyClass : IClass
{
// invalid interface implementation
// parameter type should be IClass not MyClass
string print(MyClass item)
{ return item.ToString(); }
}
我尝试通过使用泛型类型来解决接口实现问题但没有成功:
interface IClass
{
string print<T>(T item) where T : IClass;
}
class MyClass : IClass
{
string print<T>(T item) where T : MyClass
{ return item.ToString(); }
}
我该怎么办?
答案 0 :(得分:11)
使您的界面通用
interface IClass<T> where T : IClass<T>
{
string print(T item);
}
class MyClass : IClass<MyClass>
{
public string print(MyClass item)
{
return item.ToString();
}
}
答案 1 :(得分:8)
了解这是非法的原因很有帮助。您想要的功能是形式参数类型协方差,很少有语言提供它。 (埃菲尔,我认为这是一个特色。)它不常见于语言中,因为它不安全!让我举一个例子来说明:
class Animal {}
class Lion : Animal { public void Roar() { } }
class Giraffe : Animal { }
interface IFoo { void M(Animal a); }
class C : IFoo
{
public void M(Lion lion) { lion.Roar(); }
}
class P
{
public static void Main()
{
IFoo foo = new C();
foo.M(new Giraffe());
}
}
我们刚刚做了长颈鹿咆哮。
如果您查看所有类型的转换,唯一可以明智地被视为非法的是将C.M(Giraffe)
与IFoo.M(Animal)
匹配。
现在,形式参数类型逆变是 typesafe 但它在C#中是不合法的,除非在一些非常有限的情况下。如果C#支持它,它不支持它,那么你可以安全地做这样的事情:
interface IBar { void M(Giraffe g); }
class D : IBar
{
public void M(Animal animal) { ... }
}
class P
{
public static void Main()
{
IBar bar = new D();
bar.M(new Giraffe());
}
}
看看那里发生了什么? IFoo.M说&#34;我可以带长颈鹿&#34;和C.M说&#34;我可以接受任何长颈鹿,因为事实上我可以接受任何动物&#34;。如果C#支持它,那将是类型安全的,但它只以两种方式支持它:
第一个示例是类型IComparable<Animal>
的表达式可以通过相同的逻辑分配给类型IComparable<Giraffe>
的变量:比较两个动物的方法可以使用哪种方法需要比较两只长颈鹿。这是在C#4中添加的。
第二个例子是:
delegate void MyFunction(Giraffe g);
...
D d = new D();
MyFunction myfunc = d.M;
同样,我们需要一个带长颈鹿的功能,我们提供一个带任何动物的功能。此功能已在C#2中添加。
答案 2 :(得分:0)
您只需将 IClass 作为参数传递给您的方法。
interface IClass
{
string print(IClass item);
}
class MyClass : IClass
{
public string print(IClass item)
{ return item.ToString(); }
}