Методы расширения в структуре - PullRequest
31 голосов
/ 11 января 2011

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

Ответы [ 4 ]

27 голосов
/ 11 января 2011

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

namespace ExtensionMethods
{
    public static class IntExtensions
     {
        public static bool IsGreaterEqualThan(this int i, int value)
        {
            return i >= value;
        }
    }
}
19 голосов
/ 30 июля 2012

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

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

5 голосов
/ 18 марта 2015

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

public static class ExtensionMethods {

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

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

2 голосов
/ 23 августа 2013

Да, вы можете определить метод расширения для типа 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;
    }
}

Чтобы изменить содержимое структуры, параметр структуры должен быть объявлен как "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
<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
...