Объявление интерфейса для метода базового класса для поддержки IoC

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

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 ответа

Решение

Итак, я просто хочу извиниться за плохой код, который был в моем примере. Но, надеюсь, если вы посмотрите на это какое-то время, вы увидите, где это пошло не так. Но вот ответ, который я придумал. Я думаю, что может быть лучший способ преобразования, но я хотел найти решение, которое не требовало бы изменения класса 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 для реализации. Это не красиво, и вы можете применить немного больше

Я думаю, что вам нужно:

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?

Другие вопросы по тегам