Имея странную проблему с некоторым кодом С# - метод Getter для свойства отображается как виртуальный, если явно не отмечен.
Проблема проявляется с свойством DbKey в этом классе (полный код):
public class ProcessingContextKey : BusinessEntityKey, IProcessingContextKey
{
public ProcessingContextKey()
{
// Nothing
}
public ProcessingContextKey(int dbKey)
{
this.mDbKey = dbKey;
}
public int DbKey
{
get { return this.mDbKey; }
set { this.mDbKey = value; }
}
private int mDbKey;
public override Type GetEntityType()
{
return typeof(IProcessingContextEntity);
}
}
Когда я использую отражение для проверки свойства DbKey, я получаю следующий (неожиданный) результат:
Type t = typeof(ProcessingContextKey);
PropertyInfo p = t.GetProperty("DbKey");
bool virtualGetter = p.GetGetMethod(true).IsVirtual; // True!
bool virtualSetter = p.GetSetMethod(true).IsVirtual; // False
Почему virtualGetter получает значение True? Я ожидал false, учитывая, что свойство не является абстрактным и виртуальным.
Для полноты - и для отдаленной возможности они актуальны, вот объявления для BusinessEntityKey, IProcessingContextKey и IBusinessEntityKey:
public abstract class BusinessEntityKey : IBusinessEntityKey
{
public abstract Type GetEntityType();
}
public interface IProcessingContextKey : IBusinessEntityKey
{
int DbKey { get; }
}
public interface IBusinessEntityKey
{
Type GetEntityType();
}
Заранее благодарим за помощь.
Разъяснение - почему это имеет значение для меня?
Мы используем NHibernate и отслеживаем некоторые проблемы с ленивой загрузкой свойств, которые были только наполовину переопределены - виртуальный приемник, но частный сеттер. После их исправления мы добавили Unit test, чтобы поймать любые другие места, где это могло произойти:
public void RequirePropertiesToBeCompletelyVirtualOrNot()
{
var properties
= typeof(FsisBusinessEntity).Assembly
.GetExportedTypes()
.Where(type => type.IsClass)
.SelectMany(
type =>
type.GetProperties(
BindingFlags.Instance
| BindingFlags.Public
| BindingFlags.NonPublic))
.Where(property => property.CanRead
&& property.CanWrite)
.Where(property =>
property.GetGetMethod(true).IsVirtual
!= property.GetSetMethod(true).IsVirtual);
Assert.That(
properties.Count(),
Is.EqualTo(0),
properties.Aggregate(
"Found : ",
(m, p) => m + string.Format("{0}.{1}; ",
p.DeclaringType.Name,
p.Name)));
}
Этот Unit test терпел неудачу в свойстве DbKey, упомянутом выше, и я не понимал, почему.