如何通过 C# 中的扩展扩展 类 和带接口的结构?
How do you extend Classes and Structs with Interfaces via extension in C#?
我正在为 C# 中的各种 .Net Framework 数据结构制作一个实用程序库。我正在尝试将 ICloneable
添加到 Dictionary<>
。有没有办法通过扩展来做到这一点,比如你如何制作扩展方法?
为了进一步说明,在 C# 中,您可以通过在静态 class 中创建 "Extension Methods" 来扩展现有的 classes,如下所示:
public static class MyExtensions
{
public static void MyArrayExtension<T>(this T[] arg)
{
//Your code here...
}
}
这允许您在所有数组上执行该函数,如下所示:
MyArray.MyArrayExtension();
您可以创建扩展方法来扩展所有 classes 和结构,包括您在 DLL 中引用的那些,例如 .Net Framework。我目前正在使用它来帮助我设计一个实用程序库,其中包含大量我认为应该首先在 C# 中实现的有用扩展。
查看 System.Linq
时,似乎接口以某种方式添加到某些数据结构 class 中,例如 Array
和 List<>
,但仅当包含名称空间时.我正在尝试弄清楚这是如何完成的,因为我在网上搜索后找不到任何示例。
截至目前,这是不可能的。
您可以添加必要的 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<...>
,但如果你忘记了你'我们真的在那里存储其他字典类型并构建新的、正常的、不可复制的字典,有些地方它可能很快就会崩溃。
我正在为 C# 中的各种 .Net Framework 数据结构制作一个实用程序库。我正在尝试将 ICloneable
添加到 Dictionary<>
。有没有办法通过扩展来做到这一点,比如你如何制作扩展方法?
为了进一步说明,在 C# 中,您可以通过在静态 class 中创建 "Extension Methods" 来扩展现有的 classes,如下所示:
public static class MyExtensions
{
public static void MyArrayExtension<T>(this T[] arg)
{
//Your code here...
}
}
这允许您在所有数组上执行该函数,如下所示:
MyArray.MyArrayExtension();
您可以创建扩展方法来扩展所有 classes 和结构,包括您在 DLL 中引用的那些,例如 .Net Framework。我目前正在使用它来帮助我设计一个实用程序库,其中包含大量我认为应该首先在 C# 中实现的有用扩展。
查看 System.Linq
时,似乎接口以某种方式添加到某些数据结构 class 中,例如 Array
和 List<>
,但仅当包含名称空间时.我正在尝试弄清楚这是如何完成的,因为我在网上搜索后找不到任何示例。
截至目前,这是不可能的。
您可以添加必要的 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<...>
,但如果你忘记了你'我们真的在那里存储其他字典类型并构建新的、正常的、不可复制的字典,有些地方它可能很快就会崩溃。