【问题标题】:C# Template method override in concrete class from abstract base class抽象基类的具体类中的 C# 模板方法覆盖
【发布时间】:2015-03-24 06:45:27
【问题描述】:

我有以下代码,它有一个 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()MyClassMyClass2 中的实现,给出如下错误消息:

“MyObj”不包含“Name”的定义,并且找不到接受“MyObj”类型的第一个参数的扩展方法“MyObj”(您是否缺少 using 指令或程序集引用?)

【问题讨论】:

  • 顺便说一句,如果您使用常规名称(即使是示例代码)也很有用 - .NET 中的方法通常以大写字母开头。
  • @Jon,我的错,我主要使用 C++ 编写代码,而 C# 对我来说非常新,感谢您的提示。

标签: c# templates


【解决方案1】:

您似乎正在尝试为一个特定类型参数提供实现。你不能这样做,而且没有意义 - 如果 caller 传入不同类型的参数会发生什么,例如

,目前还不清楚
Base b = new MyClass2();
b.doSomething<int>(10);

(目前,您的方法中的MyObjMyObj2 被视为类型参数而不是类型本身,这就是为什么编译器对您的Name 或@987654325 一无所知@ 属性。)

听起来真的应该是通用的

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&lt;MyObj2&gt; 作为变量类型而不仅仅是Base,并且您只能将MyObj 传递给DoSomething .

(您可能还想考虑将ToString 方法设为protected 而不是public。这对于模板方法模式来说更为常见,但当然不是必需的。)

【讨论】:

  • 感谢您的建议,我已经走上了这条路,现在一切似乎都在工作。 -干杯
猜你喜欢
  • 2015-02-25
  • 1970-01-01
  • 2016-01-26
  • 2012-11-15
  • 1970-01-01
  • 2015-01-05
  • 2017-09-26
  • 2012-09-15
  • 1970-01-01
相关资源
最近更新 更多