2010-06-30 2 views
2

Так вот код:интерфейс декларации методы базового класса для поддержки 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 
{ 
} 

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

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

ответ

1

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

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

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

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

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

1

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

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, которые покрывают рамки CSLA?

+0

нет У меня нет этой книги. Мне нужно будет посмотреть, смогу ли я получить его копию. Но вы правы, между ними нет определенной связи. Хотя есть связь между T BusinessBase и U of B . Поскольку U - это интерфейс, который реализует T. Я надеялся, что с этими отношениями я кое-что увидел. – spinon

Смежные вопросы