Методы расширения в структуре

Можете ли вы добавить методы расширения в структуру?

Да, вы можете добавлять методы расширения в structs. В соответствии с определением метода расширения вы можете легко достичь этого. Ниже приведен пример метода расширения на int

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

Можно добавлять методы расширения в структуры, но есть важное предостережение. Обычные методы методов структуры принимают this как параметр ref , но C # не позволяет определять методы расширений, которые это делают. В то время как методы структуры, которые мутируют this могут быть несколько опасными (поскольку компилятор будет разрешать методы struct для вызовов только для чтения, но передавать this по значению), они также могут время от времени быть полезными, если вы будете осторожны, чтобы убедиться, что они используется только в соответствующих контекстах.

Кстати, vb.net позволяет методам расширения принимать this как параметр ByRef , независимо от того, является ли это classом, структурой или генератором неизвестной категории. Это может быть полезно в некоторых случаях, когда интерфейсы могут быть реализованы структурами. Например, если вы List.Enumerator вызвать для переменной типа List.Enumerator метод расширения, который принимает this параметр типа IEnumerator или принимает по значению a this параметр общего ограничения, IEnumerator с IEnumerator , и если метод пытается продвинуть счетчик, любое продвижение будет отменено, когда метод вернется. Тем не менее, метод расширения, который берет ограниченный общий по ссылке, (возможно, в vb.net), будет вести себя так, как должен.

Для будущих Googlers (и Bingers), вот некоторый код для расширения структуры. Этот пример превращает значение в double тип.

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

После этого вы можете использовать ToDouble() как вы используете ToString() . Будьте осторожны с элементами конверсии, такими как переполнение.

Да, вы можете определить метод расширения для типа struct / value. Однако они не имеют такого же поведения, как методы расширения для ссылочных типов.

Например, метод расширения GetA () в следующем коде C # получает копию структуры, а не ссылку на структуру. Это означает, что метод расширения C # в структуре не может изменять исходное содержимое структуры.

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

Чтобы изменить содержимое структуры, struct paramater нужно объявить как «ref». Тем не менее, «этот ref» не разрешен в C #. Самое лучшее, что мы можем сделать, это статический метод без расширения:

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