C# 基于返回类型的接口重载方法。。。
我似乎找不到任何明确规定这永远不应该做的事情,我也找不到一个推荐的方法来做这件事。所以我开始觉得我在这条路上完全错了 我正在尝试根据接口中的返回类型重载函数。基本上,我在一个接口中有15个函数,其中9个函数具有相同的名称/参数,但返回类型不同,我正在尝试隔离这一点,这样我就不必在接口中编写15个函数,我只需要一些C# 基于返回类型的接口重载方法。。。,c#,interface,overloading,C#,Interface,Overloading,我似乎找不到任何明确规定这永远不应该做的事情,我也找不到一个推荐的方法来做这件事。所以我开始觉得我在这条路上完全错了 我正在尝试根据接口中的返回类型重载函数。基本上,我在一个接口中有15个函数,其中9个函数具有相同的名称/参数,但返回类型不同,我正在尝试隔离这一点,这样我就不必在接口中编写15个函数,我只需要一些 public interface IController { IEnumerable<T> Fetch<T>(); } 公共接口IController
public interface IController
{
IEnumerable<T> Fetch<T>();
}
公共接口IController
{
IEnumerable Fetch();
}
从这里我想做一些实现,比如
public IEnumerable<T> Fetch<T>() where T : *class*
{
return dbContext.*clas*.ToList();
}
public IEnumerable Fetch(),其中T:*类*
{
返回dbContext.*.clas.*.ToList();
}
但是我收到一个编译错误
Error 1 The constraints for type parameter 'T' of method 'Controllers.Controller.Fetch<T>()' must match the constraints for type parameter 'T' of interface method 'IController.Fetch<T>()'. Consider using an explicit interface implementation instead.
错误1方法“Controllers.Controller.Fetch()”的类型参数“T”的约束必须与接口方法“IController.Fetch()”的类型参数“T”的约束匹配。请考虑使用显式接口实现。
有人对这个有什么想法吗 无法执行此操作,因为此实现与冲突 方法只能变得比类型层次结构中上面的类/接口更宽(接受更多) 现在,C#并不完全支持Liskov替代原则(在不允许加宽参数的意义上)。但这意味着,例如,如果一个方法
public class Foo {
void Bar (T parameter);
}
是在第一级中定义的,该方法不能用重写
public class SubFoo : Foo {
void Bar (SubT parameter);
}
这是因为可以在Foo
级别调用subfo
的Bar
方法。而Foo
级别有一个接受T
的契约。因此,使类型更窄并不是一种选择
如果在类层次结构中向下移动,则会注意到:
- 收益类型变得更加狭窄;及
- 参数变得更宽
T
因此仅用于指定输出类型,则确实可以使T
更窄。这叫做方差。您可以将其指定为:
public interface Foo<out T> {
T GetValue ();
}
公共接口Foo{
T GetValue();
}
这意味着Foo
是Foo
的一个子类。协方差也是如此:
public interface Foo<in T> {
void SetValue (T value);
}
公共接口Foo{
无效设定值(T值);
}
做一些假设……如果您谈论的是EF dbContext,您实际上可以这样做:
public IEnumerable<T> Fetch<T>() where T : class
{
return dbContext.Set<T>().ToList();
}
public IEnumerable Fetch(),其中T:class
{
返回dbContext.Set().ToList();
}
更一般地说,您可以这样做,其中泛型方法委托给不同类型的各种实现方法:
public IEnumerable<T> Fetch<T>() where T : class
{
if (typeof(T) == typeof(X)) return FetchX();
//Handle other types here...
}
public IEnumerable Fetch(),其中T:class
{
如果(typeof(T)=typeof(X))返回FetchX();
//在这里处理其他类型。。。
}
正如Servy指出的,要实现上述功能,还需要修改接口以包含类约束(假设需要):
公共接口IController
{
IEnumerable Fetch(),其中T:class;
}
同一个方法不能有不同的返回类型-查看该类可以发现,有时许多方法只是在返回类型上有所不同,这是必要的。您将得到许多Get{class}
方法。但是当接口没有泛型约束时,他不能这样做。@Servy,他仍然可以在接口上有泛型方法,而在接口上没有泛型约束。也许我误解了这个问题;它没有被替换的例子。不,他不能。他试图做到这一点,并在问题中得到了确切的错误信息。你只是告诉他要做他已经在做的事情,而他已经演示过的事情不起作用。@Servy,如果我理解正确的话,op试图做的是创建同一接口方法的多个实现,对每个实现使用不同的约束。当然,这是行不通的;您只能实现该方法一次,并且它必须具有相同的约束。我建议的一般方法只使用一个方法实现(与接口匹配),然后使用typeof
检查来适当地委托给内部方法。是否有多个方法甚至单个方法并不重要。在接口实现中,泛型参数不能具有接口的泛型方法所没有的约束。如果您尝试,您将得到OP正在获得的确切错误消息。
public interface IController
{
IEnumerable<T> Fetch<T>() where T: class;
}