Вчера, когда я работал с некоторыми материалами Entity Framework, я попытался написать это и получил ошибку "ObjectContext не является членом" и т.д.
context.ObjectContext.Refresh(RefreshMode.StoreWins, myObject);
Теперь контекст наследует объект DbContext, описанный здесь: http://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext(v=vs.103).aspx
Это нормальное наследование типа "есть" - мой объект контекста - объект DbContext. Класс DbContext реализует интерфейс IObjectContextAdapter, поэтому я ожидаю, что вышеприведенный код должен работать - функция-член, объявленная интерфейсом, должна быть реализована в классе DbContext, или я ожидаю, что она завершит компиляцию с "вы должны реализовать" ошибка интерфейса ". Однако, когда мы смотрели в сгенерированном определении класса, его там не было!
В конце концов, я реализовал такой вызов, который был принят компилятором.
((IObjectContextAdapter)context).ObjectContext.Refresh(RefreshMode.StoreWins, myObject);
Может ли кто-нибудь объяснить, почему я должен был это сделать, когда следующий код имеет ту же ситуацию и работает нормально?
interface IMyInterface {
int MyInterfaceMemberFunction();
}
public class MyObjectClass : IMyInterface {
public int MyInterfaceMemberFunction() { return 17; }
}
public class MyTestClass {
public int MyTestFunction() {
MyObjectClass m = new MyObjectClass();
return m.MyInterfaceMemberFunction(); //error here for EF context
}
}
Это связано с тем, что свойство ObjectContext
явно реализовано. Чтобы использовать ваш пример, чтобы продемонстрировать это:
interface IMyInterface {
int MyInterfaceMemberFunction();
}
public class MyObjectClass : IMyInterface {
// this line changed:
int IMyInterface.MyInterfaceMemberFunction() { return 17; }
}
public class MyTestClass {
public int MyTestFunction() {
MyObjectClass m = new MyObjectClass();
//return m.MyInterfaceMemberFunction(); //error here
return ((IMyInterface)m).MyInterfaceMemberFunction(); //this works
}
}
Явная реализация необходима, если у вас есть два интерфейса, которые определяют разные члены с тем же именем. Он также может использоваться для скрытия определенных элементов интерфейса, если вы хотите, чтобы они не были замечены людьми, использующими ваш класс в обычном режиме. Например, List<T>
реализует IList
, но явно реализует IList.Add(object)
чтобы вы случайно не пытались добавить что-либо, кроме T
в List<T>
.