在SomeClass </someclass>中实现IEnumerable <someclass>扩展方法

时间:2013-06-09 13:57:49

标签: c# extension-methods

我有一个这样的课程:

public class SomeClass
{
    public static IEnumerable<SomeClass> GetOutput(IEnumerable<SomeClass> items)
    {
        //Do stuff
    }
}

此类不是静态的,但我希望GetOutputIEnumerable<SomeClass>的扩展方法。因此,我创建了一个新的静态类:

public static class SomeClassExtensionMethods
{
    public static IEnumerable<SomeClass> GetOutput(this IEnumerable<SomeClass> items)
    {
        return SomeClass.GetOutput(items);
    }
}

还有更优雅的方法吗?为什么我们不允许SomeClass.GetOutput作为扩展方法?

3 个答案:

答案 0 :(得分:2)

不幸的是,没有更优雅的方法可以做到这一点。

为什么他们不被允许已经在这里回答:Why are extension methods only allowed in non-nested, non-generic static class?

答案 1 :(得分:1)

GetOutput()必须是实例方法,如果您希望扩展它,则不能是静态的。

答案 2 :(得分:0)

  

为什么我们不允许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中定义扩展方法,特别是因为它可以在同一名称空间中完成,甚至可以在{{1}相同的.cs文件中完成}