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)从派生到基的运行,但为什么统一而不是其他

方面很明显?

多谢。

C#“初始值设定项从派生运行到基数”在 Unity 中很明显,但在其他方面则不然

这是因为您将高度声明为new。通过将其声明为 new ,Derived 不会覆盖 Height,它只是隐藏它。这与初始值设定项无关。

这意味着新的实现与接口声明的虚拟属性没有任何关系,它只是碰巧具有相同的名称,从而"隐藏"了它。通过调用 Height over IHasHeight(在PrintHeightService访问该类型的字段的 Show() 方法中),将调用接口声明的属性,该属性在 Default 中实现。你只会得到Derived.Height,如果你通过类型Derived的引用来调用它。

您可以自己查看:将示例 1 中变量d的类型更改为 DefaultIHasHeight,您将看到您也将得到 150。

如果您真的想覆盖Height的实现Derived

  • Default 中将Height声明为 virtual,然后
  • Derived中将Height声明为override
  • 并删除new修饰符。