假设我有以下的类结构:
public class A {
public string Name { get; set; }
}
public class B : A {
public new string Name {
get { return base.Name; }
set { base.Name = value + " set in B"; }
}
}
public static class Test {
public static void SetAndPrintName<T>(T value, string name) where T : A {
value.Name = name;
Console.WriteLine(value.Name);
}
}
以下是运行以下代码后我期望得到的结果:
Test.SetAndPrintName(new A(), "a");
Test.SetAndPrintName(new B(), "b");
----
a
b set in B
相反,我得到了:
a
b
由于那种方法不起作用,我尝试在SetAndPrintName
中转换value
,这样做有些丑陋,但效果符合预期:
public static void SetAndPrintName<T>(T value, string name) where T : A {
if (value is B) {
((B)(object)value).Name = name;
} else {
value.Name = name;
}
Console.WriteLine(value.Name);
}
----
Test.SetAndPrintName(new A(), "a");
Test.SetAndPrintName(new B(), "b");
----
a
b set in B
我也尝试将
Name
属性设为虚拟/重写,这也可行:public class A {
public virtual string Name { get; set; }
}
public class B : A {
public override string Name {
get { return base.Name; }
set { base.Name = value + " set in B"; }
}
}
----
Test.SetAndPrintName(new A(), "a");
Test.SetAndPrintName(new B(), "b");
----
a
b set in B
问题是:为什么
new
不像其他方法一样工作?通用方法知道value
的类型是B
,那么为什么C#在三种情况中有一种情况将其视为A
?
new
关键字并不固有地意味着virtual
。泛型实现也无法改变这一点。 - haim770