C#模板方法在抽象基类的具体类中重写

时间:2015-03-24 06:45:28

标签: c# templates

我有以下代码,其中包含一个包含抽象模板方法的Base类,在派生类中使用具体类型覆盖它。

class MyObj
{
   private string name;
   public string Name { get; set; }
};

class MyObj2
{
  private string value
  public string Value { get; set; }
}

abstract class Base
{
  public abstract string toString<T>(T t);
  public void doSomething<T>(T t)
  {
    string myValue = toString<T)(t);
    ...
  }
};

class MyClass : Base
{
  public override string toString<MyObj>(MyObj o)
  {
     return o.Name;
  }
}

class MyClass2 : Base
{
  public override string toString<MyObj2>(MyObj2 o)
  {
     return o.Value;
  }
}

但是编译器不喜欢toString()MyClass中的MyClass2的实现,给出了以下行的错误消息:

  

'MyObj'不包含'Name'的定义,并且没有扩展方法'MyObj'可以找到接受类型'MyObj'的第一个参数(你是否缺少using指令或汇编引用?)

1 个答案:

答案 0 :(得分:1)

您似乎正在尝试为一个特定类型参数提供实现。你不能这样做,而且没有意义 - 如果调用者在一个不同的类型参数中传递,会发生什么情况并不清楚,例如

Base b = new MyClass2();
b.doSomething<int>(10);

(目前,方法中的MyObjMyObj2被视为类型参数而不是类型本身,这就是编译器对{{{{ 1}}或Name属性。)

听起来真的应该是 class 这是通用的:

Value

此时,以前有问题的代码无效,因为您要使用abstract class Base<T> { public abstract string ToString(T t); public void DoSomething(T t) { string myValue = ToString(t); ... } } class MyClass : Base<MyObj> { public override string ToString(MyObj o) { return o.Name; } } class MyClass2 : Base<MyObj2> { public override string ToString(MyObj2 o) { return o.Value; } } 作为变量类型而不只是Base<MyObj2>,并且您只能传递{{1转到Base

(您可能还需要考虑使MyObj方法受到保护而不是公共。这对于模板方法模式更为常见,但肯定不是必需的。)