Нет, анонимные типы не могут реализовать интерфейс. Из руководства по программированию C # :
Анонимные типы - это типы классов, которые состоят из одного или нескольких общедоступных свойств, доступных только для чтения. Никакие другие типы членов класса, такие как методы или события, не допускаются. Анонимный тип не может быть применен к любому интерфейсу или типу, кроме объекта.
Да, вы можете добавлять методы расширения в structs. В соответствии с определением метода расширения вы можете легко достичь этого. Ниже приведен пример метода расширения в int
namespace ExtensionMethods {public static class IntExtensions {public static bool IsGreaterEqualThan (это значение int i, int) {return i & gt; = value; }}}
Для будущих Googlers (и Bingers), вот некоторый код для расширения структуры. Этот пример превращает значение в тип double
.
public static class ExtensionMethods {public static double ToDouble & lt; T & gt; (это значение T), где T: struct {return Convert.ToDouble (значение); }}
После этого вы можете использовать ToDouble ()
, как вы используете ToString ()
. Будьте осторожны с элементами конверсии, такими как переполнение.
Можно добавлять методы расширения к структурам, но есть важное предостережение. Методы обычных структурных методов принимают этот
как параметр ref
, но C # не позволяет определять методы расширений, которые делают это. Хотя методы struct, которые мутируют , этот
может быть несколько опасным (поскольку компилятор разрешает использование методов struct в структурах только для чтения, но передает этот
по значению), они могут также иногда полезно, если вы будете осторожны, чтобы убедиться, что они используются только в соответствующих контекстах.
Кстати, vb.net позволяет методам расширения принимать этот
в качестве ByRef
, будь то класс, структура или общий тип неизвестной категории. Это может быть полезно в некоторых случаях, когда интерфейсы могут быть реализованы структурами. Например, если вы пытаетесь вызвать переменную типа List & lt; string & gt; .Enumerator
метод расширения, который принимает этот параметр
типа IEnumerator & lt; string & gt;
или принимает по значению a этот параметр
общего ограничения, связанного с IEnumerator & lt; string & gt;
, и если метод пытается продвинуть счетчик, любое продвижение будет отменяется, когда метод возвращается. Тем не менее, метод расширения, который берет ограниченный общий по ссылке, (возможно, в vb.net), будет вести себя так, как должен.
public static Rect CreateRectFromPercents (этот Rect rect)
, например, не работает.
– MichaelTaylor3D
1 October 2012 в 22:04
Rect
? Вы имеете в виду System.Drawing.Rectangle
или какой-то пользовательский тип?
– supercat
1 October 2012 в 22:10
WithHeight
, который возьмет Rect
и вернет новый, который был бы идентичен, кроме параметра Height
. Из любопытства API получает что-либо, препятствуя удобному доступу к полям структуры? Я нахожу подчёркнутым представление о том, что люди должны рассматривать структуры как «притворяющиеся классы», вместо того, чтобы признать, что они представляют собой другой тип сущности, к которым следует подходить по-разному. Хотя очень мало классов должны публиковать любые поля публично, я бы предположил, что подавляющее большинство структурных типов должно i> публиковать поля all i> публично.
– supercat
3 October 2012 в 18:17
Да, вы можете определить метод расширения для типа 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
ref
, было бы хорошо, но из-за того, что VB будет молча копировать вещи, которые не могут быть переданы с помощью ref
, и будет передайте копии вместо оригиналов. Если бы был способ сообщить VB.NET не делать этого (код должен вместо этого отказаться от компиляции), такие методы расширения будут семантически превосходить методы экземпляра структуры, которые изменяют этот
. Я не знаю, почему MS не предоставляет никаких средств, с помощью которых методы могут указывать, должны ли они быть invokable на созданных компилятором временных структурах.
– supercat
23 August 2013 в 21:49