结构上的扩展方法

时间:2011-01-11 09:46:13

标签: c# .net struct extension-methods

您可以向结构添加扩展方法吗?

4 个答案:

答案 0 :(得分:27)

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

上的扩展方法示例
namespace ExtensionMethods
{
    public static class IntExtensions
     {
        public static bool IsGreaterEqualThan(this int i, int value)
        {
            return i >= value;
        }
    }
}

答案 1 :(得分:19)

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

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

答案 2 :(得分:5)

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

public static class ExtensionMethods {

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

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

答案 3 :(得分:2)

是的,您可以在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
<Extension()> _ 
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
<Extension()> _ 
Public Sub SetA(ByRef [me] As FooStruct, newval As Integer) 
    [me].a = newval
End Sub