Может ли анонимный класс C# реализовать интерфейс?



возможно ли, чтобы анонимный тип реализовал интерфейс. У меня есть кусок кода, который я хотел бы работать, но не знаете как это сделать.



У меня было несколько ответов, которые либо говорят "нет", либо создают класс, который реализует интерфейс, создающий новые экземпляры этого. Это не совсем идеально, но мне интересно, есть ли механизм для создания тонкого динамического класса поверх интерфейса, который сделает это простым.



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);
}
}
}


Я нашел статья динамический интерфейс для упаковки это описывает один подход. Это лучший способ сделать это?

661   7  

7 ответов:

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

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

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

еще в 2008 году я писал пользовательский поставщик LINQ для моего тогдашнего работодателя, и в какой-то момент мне нужно было сказать" мои " анонимные классы от других анонимных, которые это означало, что они реализуют интерфейс, который я мог бы использовать для их проверки. Как мы решили это с помощью аспектов (мы использовали PostSharp), чтобы добавить реализацию интерфейса непосредственно в IL. Так что, на самом деле, разрешить анонимным классам реализовывать интерфейсы выполнимо, вам просто нужно немного согнуть правила, чтобы добраться туда.

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

лучшее решение вокруг него имеет некоторый тип динамического прокси, который создает реализацию для вас. С помощью проект LinFu вы можете заменить

select new
{
  A = value.A,
  B = value.C + "_" + value.D
};

С

 select new DynamicObject(new
 {
   A = value.A,
   B = value.C + "_" + value.D
 }).CreateDuck<DummyInterface>();

нет; анонимный тип нельзя заставить делать что-либо, кроме как иметь несколько свойств. Вам нужно будет создать свой собственный тип. Я не читал связанную статью подробно, но похоже, что она использует отражение.Эмиссия для создания новых типов на лету; но если вы ограничиваете обсуждение вещей внутри самого C# вы не можете делать то, что вы хотите.

анонимные типы могут реализовывать интерфейсы через динамический прокси.

Я написал метод расширения на GitHub и сообщение в блоге http://wblo.gs/feE для поддержки этого сценария.

метод может быть использован такой:

class Program
{
    static void Main(string[] args)
    {
        var developer = new { Name = "Jason Bowers" };

        PrintDeveloperName(developer.DuckCast<IDeveloper>());

        Console.ReadKey();
    }

    private static void PrintDeveloperName(IDeveloper developer)
    {
        Console.WriteLine(developer.Name);
    }
}

public interface IDeveloper
{
    string Name { get; }
}

самое лучшее решение-просто не использовать анонимные классы.

public class Test
{
    class DummyInterfaceImplementor : IDummyInterface
    {
        public string A { get; set; }
        public string B { get; set; }
    }

    public void WillThisWork()
    {
        var source = new DummySource[0];
        var values = from value in source
                     select new DummyInterfaceImplementor()
                     {
                         A = value.A,
                         B = value.C + "_" + value.D
                     };

        DoSomethingWithDummyInterface(values.Cast<IDummyInterface>());

    }

    public void DoSomethingWithDummyInterface(IEnumerable<IDummyInterface> values)
    {
        foreach (var value in values)
        {
            Console.WriteLine("A = '{0}', B = '{1}'", value.A, value.B);
        }
    }
}

обратите внимание, что вам нужно привести результат запроса к типу интерфейса. Возможно, есть лучший способ сделать это, но я не мог его найти.

ответ на конкретно заданный вопрос-нет. Но вы смотрели на насмешливые рамки? Я использую MOQ, но есть миллионы из них там, и они позволяют реализовать/заглушки (частично или полностью) интерфейсы в линию. Например.

public void ThisWillWork()
{
    var source = new DummySource[0];
    var mock = new Mock<DummyInterface>();

    mock.SetupProperty(m => m.A, source.Select(s => s.A));
    mock.SetupProperty(m => m.B, source.Select(s => s.C + "_" + s.D));

    DoSomethingWithDummyInterface(mock.Object);
}

Comments

    Ничего не найдено.