c# -调用扩展方法而不限定类名,实例方法语法与静态语法

本文关键字:语法 实例方法 静态 调用 扩展 方法 | 更新日期: 2023-09-27 18:08:04

我有一个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)

这仅仅是为了加强清晰度吗?

c# -调用扩展方法而不限定类名,实例方法语法与静态语法

扩展方法是静态方法,可以用第一个参数写在方法名之前,用圆点分隔,所以看起来好像它是一个实例方法:

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)
注意:如果你保留this修饰符(扩展方法声明),using static指令将不允许这种语法。