C#中用于封闭类的扩展方法

3
我有一个sealed类,
public sealed class A
{
    public string AName {get;set;}
}

有人可以像这样编写扩展方法:

public static class Extensions
{
   public static void ExtensionMethodForA (this A a)
   {
      Console.WriteLine("A's Extension method!");
   }
}

问题是,如何防止这种情况发生?

4
无法通过在类上添加关键字来阻止此功能,但如果有一个类,其他人可以为其编写扩展方法。但是,为什么这会成为问题呢?你想要阻止别人做什么? - marc_s
1
@marc_s:我正在网上发布我的自定义帮助库。但是,如果有人编写了一些“不需要的”扩展方法,创建了dll的包装器,然后发布了一个完全不同的dll呢? - now he who must not be named.
1
此功能无法“禁用”。如果您在线发布您的库,也许这是保护它的情况,签名并使用混淆(如果可能)。 - Alberto Solano
8
你已经创建了一个公共类,你希望用户能够使用它。你无法控制用户如何使用它或者将其包装起来。你可以使用sealed关键字阻止用户继承该类,但是通过扩展方法进行继承实际上只是让静态方法调用看起来更优美而已。如果你向用户提供了一个类,那么他们完全可以将所有的类都包装在自己的类中,并添加额外的函数,然后发布一个新的DLL文件,这是无法阻止的。 - Baldrick
2
@nowhewhomustnotbenamed:谁能决定哪些扩展方法是“不需要的”??? - marc_s
3个回答

15

你不需要这样做。你不能这样做。你也不应该想要这样做。

实例方法始终优先于扩展方法,因此不应该存在冲突。除此之外,它们只是语法/便利而已。别再试图让调用者的生活更加不方便了。


1
谢谢Marc。但是,我的担忧是:“我正在在线发布我的自定义帮助库。但是,如果有人编写了一些不需要的扩展方法,创建了dll的包装器,然后发布了一个完全不同的dll,那该怎么办?” - now he who must not be named.
6
+1. @nowhewhomustnotbenamed. - 你的关注点似乎是“如果有人真的使用了我的库”…还是我漏掉了什么? - Alexei Levenkov
1
@nowhewhomustnotbenamed "不需要的" - 由谁创建?如果有人创建了扩展方法,那么它必须是“需要的”。此外,他们需要部署原始dll和声明扩展方法的dll。您的关注点不太清楚。 - Marc Gravell
我认为现在应该让那个不得被提及的人开始签署他的程序集。你问了“不受欢迎”是指谁?但是想象一下,一个黑客添加了一堆间谍软件扩展方法,然后重新发布了dll文件。我认为我们可以达成共识,这些扩展方法是不受欢迎的。 - Ben
@MarcGravell 是的,马克,我知道签名不是一个安全功能。但是,对我来说,OP似乎正在将他的dll库放在互联网上供客户下载,因此签名可以帮助他的客户更加确定dll来自他本人,而且不包含任何不必要的方法。我认为这就是他担心的问题所在。这不是关于别人在你的计算机上搞破坏,而是关于他的客户确保他们没有将有问题的dll放在自己的机器上。 - Ben
显示剩余2条评论

7
你可能会对“扩展方法”这个术语感到困惑。它不是类中的方法,甚至也不是派生类中的方法;它是一种对类型进行操作的方法。它无法访问类层次结构中的私有、受保护或内部成员,因此该类仍然是封闭的。
所以,你不能也不需要这样做。

3

这样做没有意义。任何用户仍然可以创建一个实现了使用你的类类型的方法的静态类。

他们只是在声明中省略了“this”,调用者必须显式传递对象,而不是使用更简单的“.”语法。最终结果将是相同的。

扩展方法只是一种更好的表达方式,可以实现我刚刚描述的内容,而这种方式始终是可能的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接