Добавить объект, который не реализует интерфейс, но отвечает всем требованиям, к списку, ожидающему интерфейс - PullRequest
3 голосов
/ 29 октября 2011

У меня есть следующее:

List<IReport> myList = new List<IReport>();

Report myReport = TheirApi.GetReport();

myReport отвечает всем требованиям IReport, но не может реализовать IReport, потому что у меня нет доступа к источнику ItsApi.Приведение к типу IReport, очевидно, приводит к нулю, и я прочитал, что не могу привести анонимный тип к интерфейсу.

Есть ли здесь какие-либо варианты?

Класс обертки - это то, что доктор прописал:

ReportServices.GetAllCustomReports().ToList().ForEach(customReport => _customReports.Add(new ReportWrapper(customReport)));

public class ReportWrapper : IReport
{
    private Report inner;

    public int ID 
    {
        get { return inner.ID;  }
        set { inner.ID = value; }
    }
    public string Name
    {
        get { return inner.Name; }
        set { inner.Name = value; }
    }

    public ReportWrapper(Report obj)
    {
        inner = obj;
    }
}

Ответы [ 2 ]

5 голосов
/ 29 октября 2011

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

Например:

public class ReportWrapper : IReport
{
    MyObjectIsLikeReport inner;

    public ReportWrapper(MyObjectIsLikeReport obj) {
        this.inner = obj;
    }

    public void ReportMethod(int value) {
        this.inner.ReportMethod(value);
    }

    public int SomeProperty {
        get { return this.inner.SomeProperty; }
        set { this.inner.SomeProperty = value; }
    }
}

Чтобы использовать его, вы можете сделать это:

List<IReport> myList = new List<IReport>();
MyObjectIsLikeReport myReport = TheirApi.GetReport();
myList.Add(new ReportWrapper(myReport));
1 голос
/ 29 октября 2011

Рассмотрим шаблон проектирования адаптера.

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

хорошая ссылка: http://www.dofactory.com/Patterns/PatternAdapter.aspx

interface IReport
{
    void DoSomething();
}

class ReportApdapter : IReport
{
    private readonly Report _report;

    public ReportApdapter(Report report)
    {
        _report = report;
    }

    public void DoSomething()
    {
        _report.DoSomething();
    }
}

class Report
{
    public void DoSomething()
    {
    }
}


//You can use like this.
IReport report = new ReportApdapter(TheirApi.GetReport());
...