【问题标题】:Cannot inherit from generic base class and specific interface using same type with generic constraint不能使用具有泛型约束的相同类型从泛型基类和特定接口继承
【发布时间】:2010-06-15 09:43:04
【问题描述】:

对不起,奇怪的标题。我真的不知道如何更好地表达它......

我收到以下 sn-p 错误。我到处使用 Dummy 类。编译器不理解我在 DummyImplBase 上添加的约束吗?如果我直接使用 Dummy 而不是将其设置为约束,这是一个编译器错误吗?

错误 1“ConsoleApplication53.DummyImplBase”未实现接口成员“ConsoleApplication53.IRequired.RequiredMethod()”。 “ConsoleApplication53.RequiredBase.RequiredMethod()”无法实现“ConsoleApplication53.IRequired.RequiredMethod()”,因为它没有匹配的返回类型“ConsoleApplication53.Dummy”。 C:\Documents and Settings\simen\My Documents\Visual Studio 2008\Projects\ConsoleApplication53\ConsoleApplication53\Program.cs 37 27 ConsoleApplication53

public class Dummy
{
}

public interface IRequired<T>
{
    T RequiredMethod();
}

public interface IDummyRequired : IRequired<Dummy>
{
    void OtherMethod();
}

public class RequiredBase<T> : IRequired<T>
{
    public T RequiredMethod()
    {
        return default(T);
    }
}

public abstract class DummyImplBase<T> : RequiredBase<T>, IDummyRequired
    where T: Dummy
{
    public void OtherMethod()
    {
    }
}

【问题讨论】:

    标签: generics inheritance c#-3.0 interface


    【解决方案1】:

    您可以将其添加到 DummyImplBase:

       public Dummy RequiredMethod() { return base.RequiredMethod(); }
    

    编辑:或者,如果您使用的是 C# 4.0,您可以像这样更改 IRequired 的定义:

    public interface IRequired<out T>
    

    然后删除 IDummyRequired,您仍然可以将派生类分配给 IRequired&lt;Dummy&gt;(但不是 IDummyRequired)。

    第二次编辑:您的原始代码没有编译,因为 T 可能是 Dummy 或从 Dummy 派生的类。以及实现的方法

    public DummyDerived RequiredMethod() 
    

    与签名不同

    public Dummy RequiredMethod()
    

    在 IDummyDerived 中声明。

    【讨论】:

    • 通过隐藏原始方法,这似乎更像是一种乏味的 hack,但仍然......这并没有给我泛型的优势。然后我必须在派生类中这样做才能给出相同的结果。
    • 第二次编辑:啊,当然。并没有真正想到 DummyDerived 可以用作 Dummy,但这一切都是有道理的。谢谢
    【解决方案2】:

    我将 DummyImplBase 更改为:

    public abstract class DummyImplBase<T> : RequiredBase<Dummy>, IDummyRequired
            where T : Dummy
    {
        public void OtherMethod()
        {
        }
    }
    

    【讨论】:

    • 但如果我将RequiredMethod 设为虚拟并尝试使用T 或Dummy 覆盖它,则此解决方案不起作用。
    【解决方案3】:

    如果我也将 IDummyRequired 设为通用,它也可以工作,所以我想我将不得不更改我的一些设计以使其成为可能。我仍然希望找出为什么我的解决方案不起作用。

    public class Dummy
    {
    }
    
    public interface IRequired<T>
    {
        T RequiredMethod();
    }
    
    public interface IDummyRequired<T> : IRequired<T>
        where T : Dummy
    {
        void OtherMethod();
    }
    
    public class RequiredBase<T> : IRequired<T>
    {
        public T RequiredMethod()
        {
            return default(T);
        }
    }
    
    public abstract class DummyImplBase<T> : RequiredBase<T>, IDummyRequired<T>
        where T: Dummy
    {
        public void OtherMethod()
        {
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-26
      • 1970-01-01
      • 2014-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多