Объявление интерфейса для метода базового класса для поддержки IoC - PullRequest
2 голосов
/ 30 июня 2010

Итак, вот код:

interface A<T>
{
    T Save();
}

interface B : A<B>
{
}

class BusinessBase<T>
{
    T Save();
}

class D<T, U> : BusinessBase<T>
    where T : BusinessBase<T>
    where U : B<U>
{
    new U Save()
    {
        base.Save(); // this is where the error is because T can't be converted to U
    }
}

class Concrete : D<Concrete , B>, B
{
}

Итак, со всем, что я надеюсь получить, является базовый класс, который определяет все методы A, которые на самом деле просто перенаправляют на методы в C. Ночтобы поддерживать IoC и CSLA, это должно быть так.Итак, я ищу, чтобы сохранение в D возвращало U, а не T, чтобы соответствовать сигнатуре интерфейса.

Я некоторое время смотрел на это и, похоже, не мог понять, чтоЯ скучаю.

Ответы [ 2 ]

1 голос
/ 30 июня 2010

Хорошо, так что я просто хочу извиниться за плохой код, который был в моем примере.Но, надеюсь, если вы посмотрите на это какое-то время, вы увидите, где это пошло не так.Но вот ответ, который я придумал.Я думаю, что может быть лучший способ преобразования, но я хотел найти решение, которое не требовало бы изменения класса BusinessBase, поскольку это основной компонент CSLA, а не тот, который я хочу изменить.Вот код, который я придумал, который работает:

interface A<T>
{
    T Save();
}

interface IConcreteInterface : A<IConcreteInterface>
{
}

class BusinessBase<T>
    where T : BusinessBase<T>
{
    public T Save()
    {
        return (T)this;
    }
}

class D<T, U> : BusinessBase<T>
    where T : BusinessBase<T>, A<U>
    where U : A<U>
{
    public new U Save()
    {
        return (U)(object)base.Save();
    }
}

class ConcreteClass : D<ConcreteClass, IConcreteInterface>, IConcreteInterface
{
}

Изменение, которое заставило его работать, было следующим: return (U) (object) base.Save ();

До того, как меня не поместили в (U) приведение к семплу, потому что он не скомпилировался бы так.Поскольку нет никакой связи между T и U, которая может быть определена.Таким образом, единственный способ обойти это - привести возвращаемое значение T из Save к (объекту), который, конечно, будет способен приводить к чему угодно.

Вы заметили, что я также добавил ограничение типа для небольшой дополнительной защиты отприведение ошибок в том, что я удостоверяюсь, что T имеет тип A и что U имеет тип A. Это гарантирует, что оба типа имеют одинаковый интерфейс.

Если у кого-то есть что-то красивее, я открыт для предложений.Но сейчас это работает, и я чувствую себя несколько хорошо об этом.Вы можете сделать то, что я сделал, что, по крайней мере, потребовало T для реализации. Это не красиво, и вы можете применить немного больше

1 голос
/ 30 июня 2010

Я думаю, вам понадобятся:

class BusinessBase<T> : B
{
    T Save();
}

и:

class D<T, U> : BusinessBase<T>
    where T : BusinessBase<T>
    where U : B<U>
{
    new U Save()
    {
        return base.Save();
    }
}

Я думаю, что ошибка в том, что у вас нет явной или явной связи между BusinessBase<T>.Save()и B<U>, который вы пытаетесь вернуть.Возможно ли это или это сломает другие интерфейсы?

Вы просматривали Expert C # 2008 Business Objects, который охватывает платформу CSLA?

...