我有以下代码,其中包含一个包含抽象模板方法的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指令或汇编引用?)
答案 0 :(得分:1)
您似乎正在尝试为一个特定类型参数提供实现。你不能这样做,而且没有意义 - 如果调用者在一个不同的类型参数中传递,会发生什么情况并不清楚,例如
Base b = new MyClass2();
b.doSomething<int>(10);
(目前,方法中的MyObj
和MyObj2
被视为类型参数而不是类型本身,这就是编译器对{{{{ 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
方法受到保护而不是公共。这对于模板方法模式更为常见,但肯定不是必需的。)