结构上的扩展方法

你能为结构添加扩展方法吗?

是的,您可以在结构上添加扩展方法。 根据扩展方法的定义,您可以轻松实现它。 下面是int上的扩展方法示例

namespace ExtensionMethods { public static class IntExtensions { public static bool IsGreaterEqualThan(this int i, int value) { return i >= value; } } } 

可以向结构添加扩展方法,但有一个重要的警告。 普通的struct方法方法接受this作为ref参数,但C#不允许定义这样做的扩展方法。 虽然改变this方法的struct方法可能有些危险(因为编译器允许在只读结构上调用struct方法,但是通过值传递this ),如果小心确保它们是有用的,它们有时也很有用。仅在适当的环境中使用。

顺便说一句,vb.net确实允许扩展方法接受this作为ByRef参数,无论它是类,结构还是未知类通用。 在某些可能由结构实现接口的情况下,这可能会有所帮助。 例如,如果一个人试图在List.Enumerator类型的变量上调用一个扩展方法, this方法接受IEnumerator类型的this参数,或者通过值获取一个约束为IEnumerator的generics的参数,如果该方法试图推进枚举器,则该方法返回时将撤消任何进度。 但是,通过引用采用约束generics的扩展方法(可能在vb.net中)将按预期运行。

对于未来的Google员工(和Bingers),这里有一些扩展结构的代码。 此示例将值转换为double类型。

 public static class ExtensionMethods { public static double ToDouble(this T value) where T : struct { return Convert.ToDouble(value); } } 

在此之后,您可以像使用ToString()一样使用ToDouble() ToString() 。 注意溢出等转换项。

是的,您可以在struct / value类型上定义扩展方法。 但是,它们与引用类型的扩展方法没有相同的行为。

例如,以下C#代码中的GetA()扩展方法接收结构的副本 ,而不是结构的引用。 这意味着结构上的C#扩展方法无法修改原始结构内容。

 public static class TestStructExtensionMethods { public struct FooStruct { public int a; } public static int GetA(this FooStruct st) { return st.a; } } 

为了修改struct内容,struct paramater需要声明为“ref”。 但是,C#中不允许使用“this ref”。 我们能做的最好的是静态非扩展方法,如:

 // this works, but is inefficient, because it copies the whole FooStruct // just to return a public static int GetA(ref FooStruct st) { return st.a; } 

在VB.NET中,您可以将其创建为ByRef结构扩展方法,因此它可以修改原始结构:

 ' This is efficient, because it is handed a reference to the struct  _ Public Sub GetA(ByRef [me] As FooStruct) As Integer Return [me].a End Sub ' It is possible to change the struct fields, because we have a ref  _ Public Sub SetA(ByRef [me] As FooStruct, newval As Integer) [me].a = newval End Sub