为什么我们不允许将 SomeClass.GetOutput 设为扩展方法?
您可以但不能使用标准 C# 工具。
对于 C# 编译器,一个类型的扩展方法是一个静态方法,它将该类型的一个实例作为它的第一个参数,并用System.Runtime.CompilerServices.ExtensionAttribute.
在 C# 中定义扩展方法时,C# 编译器根本不允许应用该属性,建议您使用this
具有引用要求的语法。因此,您可以用其他语言定义,SomeClass
或使用在 C# 编译器完成后添加属性的工具。
PostSharp(非免费版)可以做到这一点。只需GetOutput
用不同的属性标记并编写代码来替换它System.Runtime.CompilerServices.ExtensionAttribute.
public class SomeClass
{
[ExtensionAspect]
public static IEnumerable<SomeClass> GetOutput(IEnumerable<SomeClass> items)
{
return items;
}
}
GetOutput
用 标记ExtensionAspectAttribute
,它是从 PostSharp 方面派生的。构建期间的后处理会运行该ProvideAspect
方法,该方法会添加所需的属性。
[AttributeUsage(AttributeTargets.Method)]
public class ExtensionAspectAttribute : MethodLevelAspect, IAspectProvider
{
public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
{
var constructorInfo = typeof (System.Runtime.CompilerServices.ExtensionAttribute).GetConstructor(Type.EmptyTypes);
var objectConstruction = new ObjectConstruction(constructorInfo);
var aspectInstance = new CustomAttributeIntroductionAspect(objectConstruction);
yield return new AspectInstance(targetElement, aspectInstance);
}
}
因此,在另一个引用 SomeClass 的二进制程序集的项目中,这是可行的:
var items = new [] { new SomeClass() };
var results = items.GetOutput();
这满足 C# 编译器的要求,但是 Intellisense 不将其视为扩展方法,并且 ReSharper 将其着色为错误。
当然,这是一个学术练习,因为几乎没有理由不定义扩展方法,SomeClassExtensionMethods
特别是因为它可以在同一个命名空间甚至同一个 .cs 文件中完成SomeClass.