Can you add extension methods to a struct?
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.
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
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.
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;
}
}
}