是否可以为抽象类编写扩展方法

时间:2010-09-01 11:56:43

标签: c# extension-methods abstract-class

为什么我无法扩展抽象类。有没有解决这个问题的工作?

在Silverlight中,Enum.GetNames不见了。所以,我想扩展它,并在我的实用程序集中。到那时,进入了这个。

2 个答案:

答案 0 :(得分:6)

这里的问题不是你不能将扩展方法添加到抽象类(你可以 - 你可以为任何类型添加扩展方法) - 这是你不能添加静态方法< / strong>到具有扩展方法的类型。

扩展方法是静态方法,它们将自己作为实例方法呈现在C#中。但他们仍然是静止的。向类型添加静态方法需要能够重新定义类型,只有拥有源代码才能执行此操作:)

最好的选择,如果你想要这个方法,就是编写自己的静态,看看你是否可以将代码从反射器中删除。

然而,它完全有可能不存在,因为它在Silverlight中实际上不受支持(我不知道 - 我没有调查)

修改

继续你的评论 - 我希望我在这里了解你 - 我认为你想要做的就是这样(针对object来证明这一点):

public static class ExtraObjectStatics
{
  public static void NewStaticMethod()
  {

  }
}

public class Test
{
  public void foo()
  {
    //You can't do this - the static method doesn't reside in the type 'object'
    object.NewStaticMethod();
    //You can, of course, do this
    ExtraObjectStatics.NewStaticMethod();
  }
}

如果您考虑它 - 当然,您不能将新的静态方法注入现有类型,因为,正如我在第2段中所说,您必须能够重新编译基础类型;而且根本没有办法解决这个问题。

你可以做的是(我实际上不推荐这个 - 但它是一个选项)创建一个名为Enum的新类型并将其放在一个新的命名空间中:

namespace MySystem
{
  public class Enum
  {
    public static string[] GetNames()
    {
      //don't actually know how you're going to implement it :)
    }
  }
}

现在 - 当您想要使用它时, 无法 执行的操作是:

using System;
using MySystem;

namespace MyCode
{
  public class TestClass
  {
    public static void Test()
    {
      Enum.GetNames(); //error: ambiguous between System and MySystem
    }
  }
}

因为在最外层范围内使用'System'和'MySystem'会导致编译器无法解析正确的Enum类型。

的内容是这样的:

using System;

namespace MyCode
{
  using MySystem; //move using to inside the namespace
  public class TestClass
  {
    public static void Test()
    {
      //will now work, and will target the 'MySystem.Enum.GetNames()'
      //method.
      Enum.GetNames();
    }
  }
}

现在,该命名空间内的代码(在该文件中只有)将始终将Enum解析为命名空间中的代码,因为就范围而言,这是最接近的using指令

因此,您可以将此视为覆盖整个Enum类型,以获得包含using MySystem;的给定命名空间的好处。

但是,确实如此 - System.Enum取代现有MySystem.Enum - 意味着您丢失了System.Enum类型的所有成员。< / p>

您可以通过在Enum版本的System.Enum类型中编写包装方法来解决此问题 - 确保您将类型完全限定为System.Enum

看过Reflector中的GetNames方法的实现 - 它依赖于我认为你无法构建的内部数据......但是我很想知道你是否真的能够在Silverlight中重现该方法。

答案 1 :(得分:4)

public abstract class Foo
{
  public abstract void Bar();
}

public static class FooExtensions
{
  // most useless extension method evar
  public static void CallBar(this Foo me)
  {
    me.Bar();
  }
}

当然,没问题。