C# 使用FormatterServices.GetUninitializedObject初始化的对象上的NullReferenceException
我模拟了一个DbContext,在我的测试中,我希望确保实体被标记为删除。在模拟上下文中标记每个对象时,我使用静态字典跟踪每个实体:C# 使用FormatterServices.GetUninitializedObject初始化的对象上的NullReferenceException,c#,entity-framework,nullreferenceexception,C#,Entity Framework,Nullreferenceexception,我模拟了一个DbContext,在我的测试中,我希望确保实体被标记为删除。在模拟上下文中标记每个对象时,我使用静态字典跟踪每个实体: public DbEntityEntry<T> Entry<T>(T entity) where T : class { var entry = (DbEntityEntry<T>)FormatterServices.GetUninitializedObject(typeof(DbEntityEntry<T>
public DbEntityEntry<T> Entry<T>(T entity) where T : class
{
var entry = (DbEntityEntry<T>)FormatterServices.GetUninitializedObject(typeof(DbEntityEntry<T>));
var state = entityStates[entity];
entry.State = state;
return entry;
}
public void SetEntityState(object entity, System.Data.EntityState state)
{
entityStates.Add(entity, state);
Entry(entity).State = state;
}
private static Dictionary<object, EntityState> entityStates = new Dictionary<object, EntityState>();
尝试分配给此属性会导致:
NullReferenceException: Object reference not set to an instance of an object.
显然,给定函数名时,对象没有初始化,但我不确定为什么我不能在不引发此异常的情况下为对象的属性赋值
FWIW,测试看起来像:
TripManager.DeleteTripsByForeignKey(int carId);
var trip1 = _fakeDbContext.Trips.FirstOrDefault(t => t.TripId == 1);
var entry = _fakeDbContext.Entry(trip1);
Assert.AreEqual(EntityState.Deleted, entry.State);
FormatterServices.GetUninitializedObject
不调用该类型上的任何构造函数。这意味着没有设置具有默认值或在构造函数中设置的字段。如果查看State
属性的定义(-请参阅mono版本的链接),可以看到setter依赖于构造函数中设置的\u internalEntityEntry
:
internal DbEntityEntry(InternalEntityEntry internalEntityEntry)
{
_internalEntityEntry = internalEntityEntry;
}
当然,这就是为什么你不应该乱搞FormatterServices.GetUninitializedObject
:)
如果你真的知道自己在做什么,你可以显式地调用内部构造函数并模拟
InternalEntityEntry
,但这似乎是一个非常糟糕的主意。entry==null代码>正在返回false
。但是条目的所有属性都会抛出NRE。我想知道为什么我不能为这些属性赋值。同样地,entry.ToString()
会生成:“System.Data.Entity.Infrastructure.DbEntityEntry`1[System.Object]”您必须查看属性设置器,以了解为什么不能调用它们。最有可能的是,它们依赖于空的内部状态。@JohnSaunders啊,你当然是对的。setter是:set{{u internalEntityEntry.State=value;}
,因此显然\u internalEntityEntry
为空。
internal DbEntityEntry(InternalEntityEntry internalEntityEntry)
{
_internalEntityEntry = internalEntityEntry;
}