Можете ли вы добавить методы расширения в структуру?
Методы расширения в структуре
Ответ 1
Да, вы можете добавлять методы расширения в structs. В соответствии с определением метода расширения вы можете легко достичь этого. Ниже приведен пример метода расширения для int
namespace ExtensionMethods
{
public static class IntExtensions
{
public static bool IsGreaterEqualThan(this int i, int value)
{
return i >= value;
}
}
}
Ответ 2
Можно добавлять методы расширения к структурам, но есть важное предостережение. Обычные методы методов структуры принимают this
как параметр ref
, но С# не позволяет определять методы расширений, которые это делают. Хотя методы struct, которые мутируют this
, могут быть несколько опасными (поскольку компилятор разрешает использование методов struct в структурах только для чтения, но передает this
по значению), они также могут время от времени быть полезными, если вы будете осторожны убедитесь, что они используются только в соответствующих контекстах.
Кстати, vb.net позволяет методам расширения принимать this
как параметр ByRef
, будь то класс, структура или общий тип неизвестной категории. Это может быть полезно в некоторых случаях, когда интерфейсы могут быть реализованы структурами. Например, если вы пытаетесь вызвать для переменной типа List<string>.Enumerator
метод расширения, который принимает параметр this
типа IEnumerator<string>
или принимает значение a this
параметра с общим ограничением IEnumerator<string>
, и если метод пытается продвинуть перечислитель, любое продвижение будет отменено, когда метод вернется. Тем не менее, метод расширения, который берет сдержанный общий по ссылке, (возможно, в vb.net), будет вести себя так, как должен.
Ответ 3
Для будущих Googlers (и Bingers) здесь приведен код для расширения структуры. Этот пример превращает значение в тип double
.
public static class ExtensionMethods {
public static double ToDouble<T>(this T value) where T : struct {
return Convert.ToDouble(value);
}
}
После этого вы можете использовать ToDouble()
, как вы используете ToString()
. Будьте осторожны с элементами конверсии, такими как переполнение.
Ответ 4
Да, вы можете определить метод расширения для типа struct/value. Однако они не имеют такого же поведения, как методы расширения для ссылочных типов.
Например, метод расширения GetA() в следующем коде С# получает копию структуры, а не ссылку на структуру. Это означает, что метод расширения С# в структуре не может изменять исходное содержимое структуры.
public static class TestStructExtensionMethods {
public struct FooStruct {
public int a;
}
public static int GetA(this FooStruct st) {
return st.a;
}
}
Чтобы изменить содержимое структуры, struct paramater нужно объявить как "ref". Тем не менее, "этот 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