我想我要编写的内容首先应该澄清一下,这不是我想要实现的目标。这是发生在我身上的事情,我正在努力了解它是如何可能的,所以我可以解决它。所以我们走了......
我正在使用C#,。Net 4.0。代码很大,太大了,不能超过这一切,但我试着解释一下发生了什么,希望有一些知识渊博的人会有一些想法。
在我的调用堆栈中,我有一系列通用方法,我注意到虽然值应该只是从一个传递到另一个,但它正在改变。好的,那是我的第一印象。后来我设法隔离了一个有问题的方法,当我停止时,我可以看到对象的同一属性有两个不同的值。
public class Sample : BaseClass, ISomeInterface
{
[XmlIgnore]
public new Guid Id { get; set; }
}
BaseClass和ISomeINterface定义
的重要性public Guid Id
所以现在,当我停止使用该通用方法并观察 Sample 类型的变量 data 时,我可以展开其属性并查看 Id <的第一个值< / em>的。但是,当我观看 data.Id 时,它会显示不同的值。看看你自己。
(这是一张由于声誉微不足道而无法发布的照片。抱歉)
编辑:我把它推到那里http://picturepush.com/public/7307446
那里的任何人都知道 Watch 窗口中这些值的获得方式有何不同?有什么不同?我尝试了许多不同的方法,使用反射进行投射,但总是得到与观察 data.Id 时相同的值,具有讽刺意味的是,正确的值,我期望的是另一个,难以捉摸的值。
哦,不,这不是作业;)
答案 0 :(得分:5)
new
关键字隐藏了基类成员。
将Id
中的BaseClass
属性设置为虚拟:
public class BaseClass : ISomeInterface
{
public virtual Guid Id { get; set; }
}
并在Sample
:
public class Sample : BaseClass, ISomeInterface
{
public override Guid Id { get; set; }
}
答案 1 :(得分:3)
当您在基类和实际类中定义Id时,第二个定义不会覆盖第一个但隐藏它。这意味着Sample类实际上包含两个定义,它取决于您访问的变量的静态类型。
因此:
Sample s = new Sample();
BaseClass b = (BaseClass)s;
s.Id != b.Id;
这通常不是你想要的,并且会导致非常奇怪的行为,正如你已经发现的那样:)
简单的可编译示例,演示了这一点:
class A {
public int val = 5;
public static void Main(string[] args) {
B b = new B();
A a = (A)b;
Console.WriteLine(a.val); // 5
Console.WriteLine(b.val); // 10
}
}
class B : A {
public int val = 10;
}
如果您已经遇到这种混乱但无法正确修复它,您可以将静态类型转换为您想要访问的任何版本。
答案 2 :(得分:2)
不要在Id
类中定义Sample
属性。只需从BaseClass
继承。上面的代码应该产生Sample.Id隐藏BaseClass.Id