实现IEnumerable< SomeClass>在SomeClass中
本文关键字:SomeClass 实现 IEnumerable | 更新日期: 2023-09-27 18:17:41
我有一个这样的类:
public class SomeClass
{
public static IEnumerable<SomeClass> GetOutput(IEnumerable<SomeClass> items)
{
//Do stuff
}
}
这个类不是静态的,但是我想让GetOutput
成为IEnumerable<SomeClass>
的扩展方法。因此,我创建了一个新的静态类:
public static class SomeClassExtensionMethods
{
public static IEnumerable<SomeClass> GetOutput(this IEnumerable<SomeClass> items)
{
return SomeClass.GetOutput(items);
}
}
还有什么更优雅的方法吗?为什么不允许我们将SomeClass.GetOutput
作为扩展方法?
遗憾的是,没有比这更优雅的方法了。
为什么不允许在这里已经回答了:为什么扩展方法只允许在非嵌套的,非泛型的静态类中?
GetOutput()
必须是一个实例方法,如果您希望扩展它,则不能是静态的
为什么不允许我们创建someeclass ?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
中定义扩展方法,特别是因为它可以在与SomeClass.