实现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作为扩展方法?

实现IEnumerable< SomeClass>在SomeClass中

遗憾的是,没有比这更优雅的方法了。

为什么不允许在这里已经回答了:为什么扩展方法只允许在非嵌套的,非泛型的静态类中?

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.
相同的名称空间甚至相同的.cs文件中完成。