Метод расширения структуры для всех структур [dубликат]

Нет, анонимные типы не могут реализовать интерфейс. Из руководства по программированию C # :

Анонимные типы - это типы классов, которые состоят из одного или нескольких общедоступных свойств, доступных только для чтения. Никакие другие типы членов класса, такие как методы или события, не допускаются. Анонимный тип не может быть применен к любому интерфейсу или типу, кроме объекта.

27
задан Justin 13 January 2011 в 07:01
поделиться

4 ответа

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

  namespace ExtensionMethods {public static class IntExtensions {public static bool IsGreaterEqualThan (это значение int i, int) {return i & gt; = value;  }}}  
23
ответ дан Pranay Rana 15 August 2018 в 20:33
поделиться
  • 1
    Будьте осторожны с этим, поскольку, поскольку структура передается в метод расширения BY VALUE (поскольку структуры хотят делать). Следовательно, любые изменения, которые вы вносите в структуру метода расширения, будут потеряны - если вы не вернете структуру курса (а затем сделайте что-то с этой переданной структурой назад, например, переназначьте ее для себя). Не существует способа сделать метод расширения для структуры и передать его по ссылке (в C #). – BrainSlugs83 25 August 2013 в 23:03
  • 2
    Похоже, я не могу расширить System.Drawing.Rectangle, который также является структурой и украшен Serializable и ComVisible и TypeConverter. – zionpi 25 March 2014 в 09:30

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

  public static class ExtensionMethods {public static double ToDouble & lt; T & gt; (это значение T), где T: struct {return  Convert.ToDouble (значение);  }}  

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

5
ответ дан Paul 15 August 2018 в 20:33
поделиться

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

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

19
ответ дан supercat 15 August 2018 в 20:33
поделиться
  • 1
    Итак, что может быть примером использования одного в C #? public static Rect CreateRectFromPercents (этот Rect rect) , например, не работает. – MichaelTaylor3D 1 October 2012 в 22:04
  • 2
    @ MichaelTaylor3D: Что Rect ? Вы имеете в виду System.Drawing.Rectangle или какой-то пользовательский тип? – supercat 1 October 2012 в 22:10
  • 3
    его структура, которая является частью моего api im использования. Я просто использовал его в качестве примера. Апи запрещает мне изменять его напрямую, поэтому я надеялся использовать метод расширения. Ive читал, что это возможно для структур, но я еще не видел пример. Ваше объяснение ближе всего, я могу найти. – MichaelTaylor3D 2 October 2012 в 02:48
  • 4
    Можно написать метод расширения WithHeight , который возьмет Rect и вернет новый, который был бы идентичен, кроме параметра Height . Из любопытства API получает что-либо, препятствуя удобному доступу к полям структуры? Я нахожу подчёркнутым представление о том, что люди должны рассматривать структуры как «притворяющиеся классы», вместо того, чтобы признать, что они представляют собой другой тип сущности, к которым следует подходить по-разному. Хотя очень мало классов должны публиковать любые поля публично, я бы предположил, что подавляющее большинство структурных типов должно публиковать поля all публично. – supercat 3 October 2012 в 18:17
  • 5
    @ MichaelTaylor3D: Конечно, выставляя публичные поля, станет более очевидным тот факт, что структуры не ведут себя как объекты класса, но должны сделать более очевидным, что они являются объектами класса not и не должны be expected вести себя как они. В большинстве случаев, когда структуры подходят, требуется набор из нескольких переменных, которые содержат семантически связанные, но независимые значения. Структуры с открытым полем идеально подходят, потому что именно такие структуры open-field являются . Пытаясь притвориться, что структуры - это что-то другое, и, таким образом, обойти ограничения ... – supercat 3 October 2012 в 18:28

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

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

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

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

  // это работает, но неэффективно, потому что он копирует весь FooStruct // просто для того, чтобы вернуть общедоступный статический int GetA (  ref FooStruct st) {return st.a;  }  

В VB.NET вы можете создать это как метод расширения структуры ByRef, чтобы он мог изменить исходную структуру:

  'Это эффективно  , поскольку ему передается ссылка на struct & lt; Extension () & gt;  _ Public Sub GetA (ByRef [me] As FooStruct) As Integer Return [me] .a End Sub 'Можно изменить поля структуры, потому что у нас есть ref & lt; Extension () & gt;  _ Public Sub SetA (ByRef [me] As FooStruct, newval As Integer) [me] .a = newval End Sub  
2
ответ дан user9993 15 August 2018 в 20:33
поделиться
  • 1
    То, что VB.NET позволяет методам расширений принимать структуры с помощью ref , было бы хорошо, но из-за того, что VB будет молча копировать вещи, которые не могут быть переданы с помощью ref , и будет передайте копии вместо оригиналов. Если бы был способ сообщить VB.NET не делать этого (код должен вместо этого отказаться от компиляции), такие методы расширения будут семантически превосходить методы экземпляра структуры, которые изменяют этот . Я не знаю, почему MS не предоставляет никаких средств, с помощью которых методы могут указывать, должны ли они быть invokable на созданных компилятором временных структурах. – supercat 23 August 2013 в 21:49
  • 2
    & quot; ... но за то, что VB будет молча копировать то, что не может быть передано посредством ref и будет передавать копии вместо оригиналов & quot; - Когда это делает VB? - & quot; byref & quot; скомпилирован до того же IL-кода, что и «ref». в C # - я понимаю, что все может быть передано ref в .NET - единственные вещи, которые когда-либо копируются, являются типами значений (и только тогда, когда они не переданы ref). – BrainSlugs83 25 August 2013 в 23:17
  • 3
  • 4
    Я не знал, что VB может это сделать. Похоже, что это не правда, «byref». call, но heck - для меня, что на самом деле звучит точно так же, как работать с объектом по ссылке SHOULD . - Очевидно, если вы будете делать глупое дерьмо с этим, ваш код сломается - но, честно говоря , Я действительно хочу, чтобы у C # была возможность сделать это. Вместо этого я должен писать 4 строки кода каждый раз, когда хочу передать свойство по ссылке. Однако, как я подозревал ранее, это совершенно не по теме. – BrainSlugs83 25 November 2013 в 07:47
Другие вопросы по тегам:

Похожие вопросы: