如何通过C#中的扩展来扩展带有接口的类和结构?

时间:2018-11-08 14:06:00

标签: c# interface extension-methods

我正在为C#中的各种.Net Framework数据结构创建实用程序库。我正在尝试将ICloneable添加到Dictionary<>。有没有一种方法可以通过扩展来做到这一点,例如您如何创建扩展方法?

为进一步说明,在C#中,您可以通过在静态类中创建“扩展方法”来扩展现有类,例如:

public static class MyExtensions
{
    public static void MyArrayExtension<T>(this T[] arg)
    {
        //Your code here...
    }
}

这使您可以在所有数组上执行该功能,就像这样:

MyArray.MyArrayExtension();

您可以创建扩展方法来扩展所有类和结构,包括您在DLL中引用的诸如.Net Framework的那些。我目前正在使用它来帮助我设计实用程序库,其中包含大量有用的扩展,我认为这些扩展应该首先在C#中实现。

查看System.Linq时,似乎将接口以某种方式添加到了某些数据结构类中,例如ArrayList<>,但仅当包含名称空间时才添加。我试图弄清楚这是怎么做的,因为在网上搜索后找不到任何示例。

1 个答案:

答案 0 :(得分:2)

到目前为止,这是不可能的。

您可以添加必需的Clone扩展方法,但是目前无法添加整个界面。

请记住,可以使用如下所示的现有代码编写对接口的支持检查:

if (dictionary is ICloneable cloneable)
    var clone = cloneable.Clone();

但这不能仅用于扩展某些东西,因为基础类型实际上并不实现接口


在这种思路上正在进行一些努力:

我不知道他们如何获得这些东西,所以将来是否有可能解决这个问题还有些悬而未决。


请注意,您可以使用修饰来完成此操作,但这可能需要一些工作,并且需要您使用其他类型来构造字典:

public class CloneableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, ICloneable
{
    ... methods and properties that delegate to base.XYZ

    public object Clone() => new ...
}

在构造对象的每个地方,您都必须编写以下内容:

var dictionary = new CloneableDictionary<...>();

代替:

var dictionary = new Dictionary<...>();

由于CloneableDictionary继承了Dictionary,因此即使它们的类型保持为Dictionary<...>,也可以将其放入已经存在的变量和参数中,但是如果您忘记了自己确实是在其中存储其他字典类型,并在一些可能很快掉下来的地方构造新的,正常的,不可克隆的字典。