变量如何同时具有两个值?

时间:2012-01-09 01:57:49

标签: c# .net visual-studio-debugging

我想我要编写的内容首先应该澄清一下,这不是我想要实现的目标。这是发生在我身上的事情,我正在努力了解它是如何可能的,所以我可以解决它。所以我们走了......

我正在使用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 时相同的值,具有讽刺意味的是,正确的值,我期望的是另一个,难以捉摸的值。

哦,不,这不是作业;)

3 个答案:

答案 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

的编译器警告