【问题标题】:Override Generic Method With Concrete Type (type parameter * hides class *)使用具体类型覆盖通用方法(类型参数 * 隐藏类 *)
【发布时间】:2016-06-02 19:10:48
【问题描述】:

我想覆盖派生类中的泛型方法。问题是我想要一个具体的类型参数实现:

namespace Stumped
{
    public class Generic<T> where T : new()
    {
        public virtual T Foo()
        {
            return new T();
        }

        public virtual TAnother GenericMethod<TAnother>() where TAnother : new()
        {
            return new TAnother();
        }
    }

    public class Concrete : Generic<Inner1>
    {
        // Concrete return type. Works as expected.
        public override Inner1 Foo()
        {
            return base.Foo();
        }

        // Why doesn't this make sense? Shows 'Type parameter "Inner2" hides class "Inner2"'.
        public override Inner2 GenericMethod<Inner2>()
        {
            return base.GenericMethod<Inner2>();
        }
    }

    public class Inner1 { }

    public class Inner2 { }
}

如前所述,编译器告诉我:

类型参数“Inner”隐藏类“Inner”

我希望我的实现能够正常工作,而不必在这个派生类中使用另一个泛型参数。

为什么这没有意义?

【问题讨论】:

  • 我的编译器没有显示任何东西。
  • 可能是更清晰的事情。尽管如此,该消息是有效的。如果我要尝试在覆盖的 GenericMethod 中访问 Inner2 的属性,它会告诉我该属性没有定义(因为显然我隐藏了该类)。

标签: c# generics inheritance type-parameter


【解决方案1】:

你根本做不到。

重写方法不能更改方法接口的任何部分。因为GenericMethod&lt;OtherClass&gt;()对基类有效,所以对派生类也必须有效。

这称为Liskov substitution principle

当编译器警告你时,你实际上只是声明了一个与你的类同名的普通类型参数。

【讨论】:

  • 这与我覆盖 Foo 的方式有何不同?
  • @bitbyte: Foo 不是通用的。
  • C++ 能做到这一点吗?模板函数特化?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-26
  • 1970-01-01
  • 1970-01-01
  • 2015-03-08
  • 2015-02-18
  • 2014-06-27
  • 1970-01-01
相关资源
最近更新 更多