C#“初始值设定项从派生运行到基数”在 Unity 中很明显,但在其他方面则不然
本文关键字:Unity 方面 其他 运行 派生 | 更新日期: 2023-09-27 18:32:24
我不确定这是否是一个统一错误,但谁能帮我解释为什么下面的程序在第三种情况下打印 150?
void Main()
{
// Test 1
Derived d = new Derived();
d.Height.Dump(); //Prints 10
// Test 2
IUnityContainer unityContainer = new UnityContainer();
unityContainer.Resolve(typeof(Derived)).Dump(); // Prints 10
// Test 3
unityContainer.RegisterType<IPrintHeightService<Derived>, PrintHeightService<Derived>>();
var output = unityContainer.Resolve<IPrintHeightService<Derived>>();
output.Show(); //Prints 150
}
public interface IHasHeight
{
Int32 Height {get; set;}
}
// Define other methods and classes here
public class Default : IHasHeight
{
public Int32 Height {get; set;}
public Default()
{
Height = 150;
}
}
public class Derived : Default
{
public new Int32 Height {get { return 10;}}
}
public interface IPrintHeightService<T> where T:IHasHeight, new()
{
void Show();
}
public class PrintHeightService<T> : IPrintHeightService<T> where T:IHasHeight, new()
{
private IHasHeight objectWithHeight;
public PrintHeightService(IUnityContainer unityContainer)
{
objectWithHeight = (T) unityContainer.Resolve(typeof(T));
}
public void Show()
{
Console.WriteLine(objectWithHeight.Height); // Prints 150
}
}
我怀疑这是因为初始化器是按照解释(http://blogs.msdn.com/b/ericlippert/archive/2008/02/18/why-do-initializers-run-in-the-opposite-order-as-constructors-part-two.aspx)从派生到基的运行,但为什么统一而不是其他
方面很明显?多谢。
这是因为您将高度声明为new
。通过将其声明为 new
,Derived 不会覆盖 Height,它只是隐藏它。这与初始值设定项无关。
这意味着新的实现与接口声明的虚拟属性没有任何关系,它只是碰巧具有相同的名称,从而"隐藏"了它。通过调用 Height over IHasHeight
(在PrintHeightService
访问该类型的字段的 Show()
方法中),将调用接口声明的属性,该属性在 Default
中实现。你只会得到Derived.Height
,如果你通过类型Derived
的引用来调用它。
您可以自己查看:将示例 1 中变量d
的类型更改为 Default
或 IHasHeight
,您将看到您也将得到 150。
如果您真的想覆盖Height
的实现Derived
- 在
Default
中将Height
声明为virtual
,然后 - 在
Derived
中将Height
声明为override
- 并删除
new
修饰符。