Extension methods on a struct

做~自己de王妃 提交于 2019-11-29 09:03:45

Yes, you can add extension methods on structs. As per the definition of extension method, you can easily achieve it. Below is example of extension method on int

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

It is possible to add extension methods to structures, but there is an important caveat. Normal struct methods methods accept this as a ref parameter, but C# will not allow the definition of extension methods which do so. While struct methods which mutate this can be somewhat dangerous (since the compiler will allow struct methods to be invoked on read-only structures, but pass this by value), they can also at times be useful if one is careful to ensure that they are only used in appropriate contexts.

Incidentally, vb.net does allow extension methods to accept this as a ByRef parameter, whether it is a class, struct, or an unknown-category generic. This can be helpful in some cases where interfaces may be implemented by structures. For example, if one attempts to invoke on a variable of type List<string>.Enumerator an extension method which takes a this parameter of type IEnumerator<string>, or takes by value a this parameter of a generic constrained to IEnumerator<string>, and if the method tries to advance the enumerator, any advancement will be undone when the method returns. An extension method which takes a constrained generic by reference, however, (possible in vb.net) will behave as it should.

For future Googlers (and Bingers), here's some code to extend a struct. This example turns the value into a double type.

public static class ExtensionMethods {

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

After this you can use ToDouble() like you use ToString(). Be careful on conversion items like overflows.

David Jeske

Yes, you can define an extension method on a struct/value type. However, they do not have the same behavior as extension methods on reference types.

For example, the GetA() extension method in the following C# code receives a copy of the struct, not a reference to the struct. This means that a C# extension method on a struct can't modify the original struct contents.

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

In order to modify the struct contents, the struct paramater needs to be declared as "ref". However, "this ref" is not allowed in C#. The best we can do is a static non-extension method like:

// 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;
}

In VB.NET, you can create this as a ByRef struct extension method, so it could modify the original struct:

' 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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!