C# 与泛型参数的接口vs与泛型方法的接口
假设我有这样的接口和具体的实现C# 与泛型参数的接口vs与泛型方法的接口,c#,.net,clr,C#,.net,Clr,假设我有这样的接口和具体的实现 public interface IMyInterface<T> { T My(); } public class MyConcrete : IMyInterface<string> { public string My() { return string.Empty; } } 因此,我有相同的IMyInterface2,但它通过tmy()定义了泛型行为。在我的具体类中,我想实现我的行为,
public interface IMyInterface<T>
{
T My();
}
public class MyConcrete : IMyInterface<string>
{
public string My()
{
return string.Empty;
}
}
因此,我有相同的IMyInterface2
,但它通过tmy()
定义了泛型行为。在我的具体类中,我想实现我的
行为,但对于具体的数据类型-字符串
。但C#不允许我这么做
我的问题是为什么我不能这样做?
换句话说,如果我可以将
MyInterface
创建为MyClass:MyInterface
的具体实现,并在此时停止泛型性,那么为什么我不能用泛型方法-t My()
?您的泛型方法实现也必须是泛型的,所以它必须是:
public class MyConcrete2 : IMyInterface2
{
public T My<T>()
{
throw new NotImplementedException();
}
}
用法:
var item1=newmyclass21();
var item2=新的MyClass22();
//它们都实现了IMyInterface2,所以我们可以将它们放入列表中
var list=新列表();
增加(第1项);
增加(第2项);
//迭代列表并调用我的方法
foreach(列表中的IMyInterface2项)
{
//项是IMyInterface2,因此我们有My()方法。选择T为int并使用值2调用:
项目.My(2);
//它将如何处理item1,它已经实现了我的功能?
}
因为您的接口声明了一个泛型方法T My()
,但您的实现没有实现具有该特定签名的函数
要实现您想要的功能,您需要为接口提供T generic参数,在第一个示例中:
public interface IMyInterface2<T>
{
T My();
}
public class MyConcrete2 : IMyInterface2<string>
{
public string My()
{
throw new NotImplementedException();
}
}
公共接口IMyInterface2
{
T我的();
}
公共类MyConcrete2:IMyInterface2
{
公共字符串My()
{
抛出新的NotImplementedException();
}
}
编写通用方法时,定义用于保留占位符。当您调用该方法时,实际类型就会出现在图中。所以你应该写
public T My<T>()
{
throw new NotImplementedException();
}
public T My()
{
抛出新的NotImplementedException();
}
当您调用该方法时,您可以使用那里的字符串。您的解决方案不起作用有两个原因 首先,接口是一个契约。当您实现
IMyInterface2
时,您保证将实现名为My
的函数,该函数接受泛型类型参数并返回该类型<代码>MyConcrete2不执行此操作
其次,C#泛型不允许任何类型参数专门化。(我希望C支持这个)。这是C++示例中常见的一个例子,在这里,您的示例将编译,但是如果代码不使用<代码>字符串调用<代码>我的<代码>,则任何代码的编译都不能编译。如果我可以将MyInterface的具体实现创建为MyClass:MyInterface,并在这一点上停止泛型,为什么我不能使用泛型方法-t My()?@JevgenijNekrasov检查我的更新。我显示了一种情况,您的
我的实现将失败。同意。但事实上,在这种情况下,它可以使用实际类型,并使用对象的多态行为调用具体实现。您想怎么做?我想停止泛型,就像我可以使用泛型接口一样,例如MyClass:MyInterfaceI知道如何实现我想要的,我想知道为什么我不能停止泛化,因为我可以使用接口。在继承类型时,你不能减少能力,你只能增加它们。
var item1 = new MyClass21();
var item2 = new MyClass22();
// they both implement IMyInterface2, so we can put them into list
var list = new List<IMyInterface2>();
list.Add(item1);
list.Add(item2);
// iterate the list and call My method
foreach(IMyInterface2 item in list)
{
// item is IMyInterface2, so we have My<T>() method. Choose T to be int and call with value 2:
item.My<int>(2);
// how would it work with item1, which has My<string> implemented?
}
public interface IMyInterface2<T>
{
T My();
}
public class MyConcrete2 : IMyInterface2<string>
{
public string My()
{
throw new NotImplementedException();
}
}
public T My<T>()
{
throw new NotImplementedException();
}