我正在为应用程序提供支持,所以我不十分了解事情的产生方式。但我会尽力解释我的问题,因此在您的帮助下我可能会解决问题或提出更好的问题。 我来啦: 我正在获取一个对象,并且在调试时,我看到2个具有相同名称(Id)的属性,我希望从与cero不同的属性中获取值。使用entity.Id返回零值。并且(在此示例中)我想返回具有118值的那个
答案 0 :(得分:1)
问题
您的问题很可能是因为new
运算符已用于重新声明基类中已经存在的属性。如下图所示:
public class A
{
public int Id
{
get;
set;
}
}
public class B : A
{
public new int Id //<-- new is used
{
get;
set;
}
}
然后,如果我们有一个具有这样约束的通用方法:
public static void Do<TEntity>(TEntity entity) where TEntity : A
{
Console.WriteLine("entity Id is: {0}", entity.Id);
}
我们只能使用A
类型的事物,而不能使用B
类型的事物。由于我们从未将1
分配给A.Id
,因此它仍然具有值0
。为了证明这一点,我们可以像上面这样调用上面的方法:
var b = new B();
b.Id = 1;
Do(b);
并将其写入控制台:
实体ID为:0
但是,如果您这样做并强迫编译器选择B.Id
,则Id
将具有1
:
Console.WriteLine("entity Id is: {0}", (entity as B).Id);
解决方案
解决方案将非常棘手。
第一种选择是使用as
运算符,就像我在上面所做的那样,但是您的方法将不再是通用的。
第二个选项是弄清楚为什么使用new
运算符来隐藏基本成员。可能是很好的原因,但很可能是因为:基类是手写的,继承类是由EF生成的,并且由于它们都具有Id
,因此编译失败。然后,开发人员创建了一个局部类,并使用Id
运算符在该类中重新声明了new
属性,从而进行了黑客入侵。如果没有充分的理由,请不要继承基类,但是您将无法使用通用方法。
第三个选择是从基类中删除Id
属性,但这也会破坏很多代码。
如您所见,问题是体系结构的:这是一个糟糕的设计。
临时修订
作为临时解决方案,请为自己创建一个任务,这样您就不会忘记与团队成员讨论此问题。现在,只需执行以下操作即可:
// HACK: @Devs: I had to do this as a temp fix but we need to discuss why I did this
// and discuss the possible fixes.
B b = entity as B;
if (b != null)
{
Console.WriteLine("entity Id is: {0}", b.Id);
}