0

我不确定这是否是一个统一错误,但谁能帮我解释为什么下面的程序在第三种情况下打印 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) 但为什么它在统一时很明显,而不是在其他方面?

非常感谢。

4

1 回答 1

4

这是因为您将 Height 声明为new. 通过将其声明为new,派生不会覆盖高度,它只是隐藏它。这与初始化程序无关。

这意味着新实现与接口声明的虚拟属性没有任何关系,它恰好具有相同的名称,因此“隐藏”了它。通过调用 Height over IHasHeight(在您访问具有该类型的字段的Show()方法中),接口声明的属性被调用,该属性在. 如果您通过 type 的引用调用它,您只会得到。PrintHeightServiceDefaultDerived.HeightDerived

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

如果你真的想覆盖HeightinDerived

  • 声明HeightvirtualinDefault然后
  • 声明Heightoverride_Derived
  • 并删除new修饰符。
于 2012-04-25T14:14:45.157 回答