C# 未确定类型参数

use*_*179 0 .net c# generic-type-argument generic-type-parameters

我有一个需要显式类型参数的 C# 方法,但收到此错误:

error CS0411: The type arguments for method 'Test.TargetMethod<TObjectFactory, TResult>(TObjectFactory)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

我通常可以通过指定适当的参数(常规参数,而不是类型参数)来解决这个问题,但在这种情况下,我可能必须明确声明类型参数。但我不想指定类型参数,因为它会增加冗长。

TargetMethod请参阅下面的示例代码,特别是底部附近的两个调用。在第一次调用 时TargetMethod,类型参数应该很明显,因为我传入了 a StringFactory,它只返回 a string。(请参阅 的泛型类型约束TargetMethod。)有没有办法让 C# 意识到它拥有它需要知道的所有内容并且不需要类型参数?我想知道是否需要更改签名,TargetMethod以便 C# 可以理解发生了什么。谢谢。

public interface IObjectFactory<out TResult>
{
    TResult Construct();
}

public class StringFactory : IObjectFactory<string>
{
    public string Construct() { return ""; }
}

public static class Test
{
    //I need to be able to pass in a generic factory to this method.
    //I also need it to return a generic result.
    //This is a mandatory part of the design, and on its own, it works fine.
    private static TResult TargetMethod<TObjectFactory, TResult>(TObjectFactory objectFactory)
        where TObjectFactory : IObjectFactory<TResult>
    {
        return objectFactory.Construct();
    }

    //This method can't easily call the other one.
    public static void EntryMethod()
    {
        StringFactory stringFactory = new StringFactory();
        //On the below line, how can I get C# to figure out that TargetMethod will return a string?
        string result1 = TargetMethod(stringFactory);//compilation error
        //I can do the below, but I don't want to have to specify type arguments each time.
        string result2 = TargetMethod<StringFactory, string>(stringFactory);
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 5

在下面的行中,如何让 C# 确定 TargetMethod 将返回一个字符串?

你不能。查看你的方法声明:

TResult TargetMethod<TObjectFactory, TResult>(TObjectFactory objectFactory)
Run Code Online (Sandbox Code Playgroud)

你的参数只是参考TObjectFactory,不是TResult。类型推断使用参数和参数,而不使用方法结果的使用方式或类型参数的类型约束。尽管TObjectFactory限制为实现IObjectFactory<TResult>,但并不用于推断 的类型参数TResult

的类型参数TResult根本无法从常规参数中推断出来,因为类型参数不会出现在参数列表中的任何位置。

另一种方法是将方法更改为:

TResult TargetMethod<TResult>(IObjectFactory<TResult> factory)
Run Code Online (Sandbox Code Playgroud)

毕竟,TObjectFactory据我们所知,您实际上并不需要知道您的方法。

(或者更简单地说,完全摆脱接口并使用Func<T>,只需使用简单的工厂方法并在需要时从中构造委托......)