2

所以这里是代码:

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 以匹配接口签名..

我已经盯着这个看了一段时间,似乎无法弄清楚我错过了什么。

4

2 回答 2

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>您尝试返回的之间没有任何隐式或显式联系。这是可能的还是会破坏其他接口?

您是否浏览过涵盖 CSLA 框架的 Expert C# 2008 Business Objects?

于 2010-06-30T00:43:35.133 回答
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
{
}

使它起作用的更改是:return (U)(object)base.Save();

在我没有在样本中加入 (U) 之前,因为它不会像那样编译。因为 T 和 U 之间没有可以确定的关系。所以解决这个问题的唯一方法是将返回的 T 从 Save 转换为 (object) ,这当然可以转换为任何东西。

您注意到我还添加了一个类型约束,以增加对强制类型转换错误的保护,因为我确保 T 属于 A 类型,而 U 属于 A 类型。这确保了两种类型具有相同的接口。

如果有人有更漂亮的东西,我愿意接受建议。但是现在这正在起作用,我对此感觉有些好。你可以做我所做的,至少需要 T 来实现它并不漂亮,你可以执行更多

于 2010-06-30T06:12:33.387 回答