Extension methods on a struct

前端 未结 4 415
野趣味
野趣味 2020-12-17 07:46

Can you add extension methods to a struct?

相关标签:
4条回答
  • 2020-12-17 08:08

    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.

    0 讨论(0)
  • 2020-12-17 08:31

    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
    
    0 讨论(0)
  • 2020-12-17 08:33

    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.

    0 讨论(0)
  • 2020-12-17 08:34

    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;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题