1

I have a class like this:

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

This class is not static, but I want to make GetOutput an extension method for IEnumerable<SomeClass>. As such, I create a new static class:

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

Is there any more elegant way to do this? Why aren't we allowed to make SomeClass.GetOutput an extension method?

4

3 回答 3

2

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

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

于 2013-06-09T14:17:38.470 回答
1

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

于 2013-06-09T13:59:40.773 回答
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特别是因为它可以在同一个命名空间甚至同一个 .cs 文件中完成SomeClass.

于 2013-06-10T05:05:45.257 回答