Возможно ли, чтобы анонимный тип реализовывал интерфейс?
У меня есть кусок кода, который я хотел бы работать, но не знаю, как это сделать.
У меня была пара ответов, которые либо говорят «нет», либо создают класс, который реализует интерфейс, создавая новые экземпляры этого. Это не совсем идеально, но мне интересно, есть ли механизм для создания тонкого динамического класса поверх интерфейса, который сделал бы это простым.
public interface DummyInterface
{
string A { get; }
string B { get; }
}
public class DummySource
{
public string A { get; set; }
public string C { get; set; }
public string D { get; set; }
}
public class Test
{
public void WillThisWork()
{
var source = new DummySource[0];
var values = from value in source
select new
{
A = value.A,
B = value.C + "_" + value.D
};
DoSomethingWithDummyInterface(values);
}
public void DoSomethingWithDummyInterface(IEnumerable<DummyInterface> values)
{
foreach (var value in values)
{
Console.WriteLine("A = '{0}', B = '{1}'", value.A, value.B);
}
}
}
Я нашел статью Динамическая упаковка интерфейса, которая описывает один подход. Это лучший способ сделать это?
c#
anonymous-types
Ник Рэнделл
источник
источник
Ответы:
Нет, анонимные типы не могут реализовать интерфейс. Из руководства по программированию на C # :
источник
Хотя это может быть двухлетний вопрос, и хотя все ответы в теме достаточно верны, я не могу удержаться от желания сказать вам, что на самом деле возможно, чтобы анонимный класс реализовал интерфейс, даже если для этого требуется немного творческого мошенничества, чтобы попасть туда.
Еще в 2008 году я писал собственного поставщика LINQ для своего тогдашнего работодателя, и в какой-то момент мне нужно было иметь возможность отличать «мои» анонимные классы от других анонимных, что означало, что они реализуют интерфейс, который я мог бы использовать для проверки типов их. Мы решили это с помощью аспектов (мы использовали PostSharp ), чтобы добавить реализацию интерфейса непосредственно в IL. Таким образом, на самом деле, позволяя анонимным классам реализовывать интерфейсы, выполнимо , вам просто нужно немного изменить правила, чтобы попасть туда.
источник
Приведение анонимных типов к интерфейсам - это то, чего я давно хотел, но, к сожалению, текущая реализация вынуждает вас иметь реализацию этого интерфейса.
Лучшее решение - использовать динамический прокси-сервер, который создает реализацию для вас. Используя отличный проект LinFu, вы можете заменить
с
источник
DynamicObject
тип Линьфа?System.Dynamic.DynamicObject
имеет только защищенный конструктор (по крайней мере, в .NET 4.5).DynamicObject
которая предшествовала версии DLRАнонимные типы могут реализовывать интерфейсы через динамический прокси.
Я написал метод расширения для GitHub и пост в блоге http://wblo.gs/feE для поддержки этого сценария.
Метод можно использовать так:
источник
Нет; анонимный тип не может делать ничего, кроме как иметь несколько свойств. Вам нужно будет создать свой собственный тип. Я не читал связанную статью подробно, но похоже, что она использует Reflection.Emit для создания новых типов на лету; но если вы ограничиваете обсуждение вещами внутри самого C #, вы не можете делать то, что хотите.
источник
Лучшее решение - просто не использовать анонимные классы.
Обратите внимание, что вам нужно привести результат запроса к типу интерфейса. Возможно, есть лучший способ сделать это, но я не смог его найти.
источник
values.OfType<IDummyInterface>()
вместо приведения. Он возвращает только те объекты в вашей коллекции, которые на самом деле можно привести к этому типу. Все зависит от того, что вы хотите.Ответ на конкретно заданный вопрос - нет. Но вы смотрели на насмешливые рамки? Я использую MOQ, но их миллионы, и они позволяют вам реализовать / заглушить (частично или полностью) встроенные интерфейсы. Например.
источник
Другой вариант - создать один конкретный реализующий класс, который принимает лямбда-выражения в конструкторе.
Если все, что вы когда-либо собираетесь сделать, это преобразовать
DummySource
вDummyInterface
, то было бы проще иметь только один класс, который принимаетDummySource
в конструкторе и реализует интерфейс.Но, если вам нужно преобразовать многие типы
DummyInterface
, это гораздо меньше, чем котельная плита.источник