为什么此属性Getter是虚拟的? [英] Why is this property Getter virtual?

查看:48
本文介绍了为什么此属性Getter是虚拟的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

某些C#代码存在一个奇怪的问题-属性的Getter方法在未显式标记时显示为虚拟.

Having a strange issue with some C# code - the Getter method for a property is showing up as virtual when not explicitly marked.

该类的DbKey属性出现问题(完整代码):

The problem exhibits with the DbKey property on this class (code in full):

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属性时,得到以下(意外)结果:

When I use reflection to inspect the DbKey property, I get the following (unexpected) result:

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.

Why does virtualGetter get set to True? I expected false, given that the property is neither abstract nor virtual.

出于完整性考虑,并且与远程可能性相关,这是BusinessEntityKey,IProcessingContextKey和IBusinessEntityKey的声明:

For completeness - and for the remote possibilty they are relevant, here are the declarations for BusinessEntityKey, IProcessingContextKey, and IBusinessEntityKey:

public abstract class BusinessEntityKey : IBusinessEntityKey
{
    public abstract Type GetEntityType();
}

public interface IProcessingContextKey : IBusinessEntityKey 
{
    int DbKey { get; }
}

public interface IBusinessEntityKey
{
    Type GetEntityType();
}

预先感谢您的帮助.

说明-为什么这对我很重要?

Clarification - why does this matter to me?

我们正在使用NHibernate并跟踪了一些延迟加载问题,这些问题仅是可以半覆盖的属性-虚拟getter但私有setter.解决这些问题后,我们添加了一个单元测试来捕获可能发生这种情况的其他任何地方:

We're using NHibernate and traced some issues with lazy loading to properties that were only half overridable - virtual getter but private setter. After fixing these up, we added a Unit test to catch any other places where this could occur:

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)));
}

此单元测试的上述DbKey属性失败,我不明白为什么.

This unit test was failing on the DbKey property mentioned above, and I didn't understand why.

推荐答案

它是虚拟的,因为它实现了接口方法.就CLR而言,接口实现方法始终是虚拟的.

It's virtual because it implements an interface method. Interface implementation methods are always virtual as far as the CLR is concerned.

这篇关于为什么此属性Getter是虚拟的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆