为泛型方法调用错误的重载

时间:2013-10-23 17:49:58

标签: c# generics extension-methods

我有两种非常相似的通用方法。我们的想法是可以使用显式返回类型调用一个,而另一个推断返回类型与提供的obj相同。

第一种方法称为:RestResponse response = myCat.Put<RestResponse>()

//Perform a PUT on the current resource, returning the server response deserialized to a new object of the specified type.</summary>
//<typeparam name="T">The expected type of the resource post response. Use 'IRestResponse' to skip deserializing the request.</typeparam>
public static T Put<T>(this APIResource obj, List<Parameter> parameters = null)
{
    if (parameters == null) parameters = new List<Parameter>();
    parameters.Add(new Parameter() { Value = obj, Type = ParameterType.RequestBody });
    return RequestHelper<T>(obj.collection_name + "/" + obj.id, Method.PUT, parameters);
}

自动调用Cat response = myCat.Put();

//<typeparam name="O">(Automatically Inferred) The type of the current resource, which is also the expected type of the resource request response.</typeparam>
public static O Put<O>(this O obj, List<Parameter> parameters = null) 
     where O : APIResource 
{ return obj.Put<O>(parameters); } //I want to call the first method here.

现在,我可以看到这些定义是如何模糊不清的。奇怪的是,没有编译错误,但在运行时,我得到堆栈溢出,因为第二种方法只是自己调用。

有没有办法让第二种方法调用第一种方法而不改变任何一种方法的名称?

2 个答案:

答案 0 :(得分:2)

当决定两种方法的“更好”时(这是在方法调用与多个签名匹配时所做的),优先选择“更接近”调用点的方法。

两个更常见的例子:

  1. 如果在同一类型中定义了一个方法而另一个方法没有定义,则该类型中的方法获胜。

  2. 如果一个方法位于同一个命名空间而另一个方法不在同一个命名空间中,那么同一命名空间中的方法就会胜出。

  3. 解决歧义的一种方法是不利用它是一种扩展方法的事实;把它称为好像不是(它仍然可以是一种扩展方法,供外部呼叫者使用)。

    public static O Put<O>(this O obj, List<Parameter> parameters = null) 
         where O : APIResource 
    { return OtherPutClass.Put<O>(obj, parameters); }
    

答案 1 :(得分:-1)

您是否尝试过显式转换为正确的类型?

看起来像是:

public static O Put<out O>( this O obj , List<Parameter> parameters = null ) where O:APIResource
{
  return ((APIResource)obj).Put<O>(parameters) ;  //I want to call the first method here.
}

public static O Put<out O>( this O obj , List<Parameter> parameters = null ) where O:APIResource
{
  return .Put<O>( (APIResource)obj , parameters) ;  //I want to call the first method here.
}

我们可以得到你想要的东西。

然而,类型系统与您的意图相混淆的事实可能表明,有人试图修复线下的​​错误也会被混淆。