【问题标题】:Interface declaration for base class method to support IoC基类方法的接口声明以支持 IoC
【发布时间】:2010-06-30 00:26:59
【问题描述】:

代码如下:

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

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

【问题讨论】:

    标签: c# .net design-patterns interface csla


    【解决方案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&lt;T&gt;.Save() 和您尝试返回的 B&lt;U&gt; 之间没有任何隐式或显式连接。这是可能的还是会破坏其他接口?

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

    【讨论】:

    • 不,我没有那本书。我得看看我能不能得到它的副本。但你是对的,两者之间没有明确的联系。虽然 BusinessBase 的 T 和 B 的 U 之间存在联系。因为 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 转换为 (object),然后它当然可以转换为任何东西。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-24
      • 2014-05-09
      相关资源
      最近更新 更多