Подтвердить что ты не робот

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

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

4b9b3361

Ответ 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