C#方法泛型返回类型转换

Dev*_*ruz 9 c# generics

我试图在具有泛型返回类型的接口中创建一个方法,但我无法将泛型强制转换为特定的类型/类.但是,如果我将泛型放在接口上而不是方法上,我可以进行转换.

换句话说,为什么这样做

public class Rain {
    public string propA {get;set;}
}
public interface IFoo<T> {
    T foo();
}

public class Bar : IFoo<Rain> {
    Rain foo() { 
        //...
        return new Rain();
    }
}

public bar = new Bar();
Rain rain = bar.foo();
Run Code Online (Sandbox Code Playgroud)

但是不可能这样做吗?

public class Rain {
    public string propA {get;set;}
}
public interface IFoo {
    T foo<T>();
}

public class Bar : IFoo {
    T foo<T>() { 
        //...
        return new Rain();
    }
}

public bar = new Bar();
Rain rain = bar.foo<Rain>();
Run Code Online (Sandbox Code Playgroud)

有没有其他方法(不使用Convert.ChangeType())?

Zoh*_*led 10

第二个代码片段是不可能编译的,因为Rain不是T.

在类中提供type参数时,没有问题,因为该方法只能返回类声明中已提供的类型.换句话说 - T foo()成为Rain foo.

但是,当类型参数提供给方法时,该方法必须返回提供给它的任何类型 - 因此您不能返回除此之外的任何类型T.换句话说,编译器不能强制执行仅使用的调用方法foo<Rain>(),但它可以强制执行foo返回的方法T.


mar*_*sze 3

区别在于:

// On this line you specify that the interface's generic type paramter 'T' is of type 'Rain',
// so the method implements the interface and returns a 'Rain'
public class Bar : IFoo<Rain> {
    Rain foo() { // <= implements IFoo<Rain>.foo, where T = Rain so foo returns 'Rain'
        return new Rain();

// In this version, the generic type parameter is declared on the method. It could be any type when the method is called, yet you always return a 'Rain'
public class Bar : IFoo {
    T foo<T>() { // <= implements IFoo.foo<T> but the type of T is not specified yet
        return new Rain();
Run Code Online (Sandbox Code Playgroud)

对此的“解决方案”取决于您的意图。

  • 为什么你不想在接口上使用通用参数?
  • foo另外,如果您总是返回,为什么要在方法上使用通用参数呢Rain?

当然,无论如何,你都可以像这样进行转换:

T Foo<T>()
{
    object result;
    result = new Rain();
    return (T)result; // note, this will throw at runtime if 'result' cannot be cast to 'T'
}

// call like this:
Bar.Foo<Rain>();
Run Code Online (Sandbox Code Playgroud)

但我认为你的第一种方法IFoo<T>非常有意义,所以为什么不使用它呢?

更新

根据您的评论:您还可以定义多个通用参数:

public interface IFoo<T1, T2>
{
    T1 foo();
    T2 foo2();
}

// implementation:
public class Bar : IFoo<Rain, Other>
{
    Rain foo() { /* ... */ }
    Other foo2() { /* ... */ }
}
Run Code Online (Sandbox Code Playgroud)

  • @DevelopeCruz“另外,我想让该接口的各种实现来决定返回类型是什么” - 在这种情况下,接口的作用非常有限,分别没有任何用处。如果您的接口不限制实现可以返回的内容,则只需删除该接口即可。或者更好的是,重新考虑您的设计。 (2认同)