C# - 调用扩展方法,不使用类名,实例方法语法与静态语法

时间:2016-09-21 19:09:21

标签: c#

我有一个IResult<TResult>泛型类,子类Success<TResult>Failure<TResult>用于表示成功/失败的结果和相关信息。减少遍布各地的通用参数的繁琐重复(当TResult只是一个类时它很容易,但如果有嵌套的泛型则变得非常难看),我有一个扩展方法,以帮助建立:

public static class SuccessExtensionsClass
{
    public static BuildSuccess<TResult> Success<TResult>(this TResult result)
    {
        return new Success<TResult>(result);
    }
}

现在我可以这样做:

TResult blah = new TResult();

然后

return blah.BuildSuccess();

到目前为止一切顺利。我不需要根据需要为扩展方法提供泛型类型。

但是,如果我使用语法:

BuildSuccess(blah)

我收到有关缺少的泛型类型参数的编译器错误。另一方面,如果我将其更改为:

BuildSuccess<TResult>(blah)

在我使用普通静态方法指定类之前,它无法找到该方法:

SuccessExtensionClass.BuildSuccess<TResult>(blah)

工作正常,如下:

SuccessExtensionClass.BuildSuccess(blah)

为什么呢?或者,更具体地说,是什么激发了这种选择?编译器在两种情况下都具有相同的可用信息,因为在调用BuildSuccess(blah)时关于缺少泛型类型的错误非常清楚。是否只是一种设计选择,只有在扩展语法中才能调用扩展方法而不用其类名限定?这仅仅是出于代码清晰度的目的还是我没有想到的另一个原因?

作为后续行动,为什么静态语法不会受到与实例方法语法相同的规则的约束,如果您已显式导入命名空间,编译器将(仅)解析名称?

编辑,希望更清晰:

在实例语法中,我不必将扩展方法称为:

blah.SuccessExtensionsClass.BuildSuccess()

但是在静态语法中我需要将其称为:

SuccessExtensionsClass.BuildSuccess(blah)

这只是为了强制清晰吗?

1 个答案:

答案 0 :(得分:1)

扩展方法是静态方法,可以使用在方法名称之前写入的第一个参数来调用,用点分隔它,因此它看起来好像是一个实例方法:

blah.BuildSuccess()

在这个例子中,blah实际上是静态方法的第一个参数。这就是扩展方法的用途。

您似乎需要另一种语法,即:

BuildSuccess(blah)

当然,如果您恰好位于定义方法的类中,那么该语法已经合法。但是,如果您希望更普遍地应用该语法,那么您所寻求的不是扩展方法,而只是 using static指令

删除this修饰符:

namespace Your.Relevant.Name
{
  public static class SuccessHelperMethods
  {
    public static Success<TResult> BuildSuccess<TResult>(TResult result)
    {
      return new Success<TResult>(result);
    }
  }
}

然后用:

using static Your.Relevant.Name.SuccessHelperMethods;

在编译单元(代码文件)的顶部,这种语法是合法的:

BuildSuccess(blah)

注意:如果保留using static修饰符(扩展方法声明),则this指令将允许此语法。