C# 基于返回类型的接口重载方法。。。

C# 基于返回类型的接口重载方法。。。,c#,interface,overloading,C#,Interface,Overloading,我似乎找不到任何明确规定这永远不应该做的事情,我也找不到一个推荐的方法来做这件事。所以我开始觉得我在这条路上完全错了 我正在尝试根据接口中的返回类型重载函数。基本上,我在一个接口中有15个函数,其中9个函数具有相同的名称/参数,但返回类型不同,我正在尝试隔离这一点,这样我就不必在接口中编写15个函数,我只需要一些 public interface IController { IEnumerable<T> Fetch<T>(); } 公共接口IController

我似乎找不到任何明确规定这永远不应该做的事情,我也找不到一个推荐的方法来做这件事。所以我开始觉得我在这条路上完全错了

我正在尝试根据接口中的返回类型重载函数。基本上,我在一个接口中有15个函数,其中9个函数具有相同的名称/参数,但返回类型不同,我正在尝试隔离这一点,这样我就不必在接口中编写15个函数,我只需要一些

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
的契约。因此,使类型更窄并不是一种选择

如果在类层次结构中向下移动,则会注意到:

  • 收益类型变得更加狭窄;及
  • 参数变得更宽
但是,C#支持接口级别的方差/协方差。如果
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;
}