C# 使用以另一个类命名的泛型属性时,引用该类的常量字段

C# 使用以另一个类命名的泛型属性时,引用该类的常量字段,c#,generics,constants,C#,Generics,Constants,假设我的类结构与此类似: public interface IArbitraryQualifier { int Qualification { get; } } public class ArbitraryQualifier : IArbitraryQualifier { public const int MIN_QUALITY = 1; public int Qualification { get; } } public class Person {

假设我的类结构与此类似:

public interface IArbitraryQualifier {
    int Qualification { get; }
}
public class ArbitraryQualifier : IArbitraryQualifier {
    public const int MIN_QUALITY = 1;

    public int Qualification { get; }    
}
public class Person {
    public IArbitraryQualifier ArbitraryQualifier { get; }
    public bool AmIARealBoy 
    { 
      get 
      { 
        return this.ArbitraryQualifier.Qualification >= ArbitraryQualifier.MIN_QUALITY; 
      } 
    }
}
如何从类内Person引用类ArbitraryQualifier中的常量字段MIN_QUALITY?它不断生成错误IDE0009。。。不包含…的定义。。。这建议我加上“this”或“me”限定

如果我重命名属性或具体类,它就可以正常工作,但我不想这样做,因为我使用的是一个名为与属性相同的样板类

请注意,这也适用于抽象类和泛型类型,但不适用于具体类型。例如,此处没有编译错误:

public class ArbitraryQualifier {
    public const int MIN_QUALITY = 1;

    public int Qualification { get; }    
}
public class Person {
    public ArbitraryQualifier ArbitraryQualifier { get; }
    public bool AmIARealBoy 
    { 
      get 
      { 
        return this.ArbitraryQualifier.Qualification >= ArbitraryQualifier.MIN_QUALITY; 
      }
    }
}

另外,为什么在其他类不编译的情况下会编译该类?

如果要访问静态属性namespace.classname.propertyname,可以引用该类的完全限定名

例如,下面的命名空间测试是FQDN的一部分,它还说明了使用以下命令编写只读属性的另一种方法:

如果一个类依赖于IArbitraryQualifier,那么除了它实现了IArbitraryQualifier之外,它不应该知道任何关于实现的信息。这意味着人们不应该知道IArbitraryQualifier的实现有一个名为MIN_QUALITY的常量。它应该只知道接口中声明了什么

例如,如果我们创建IArbitraryQualifier的另一个实现会怎么样:

。。。然后这样做:

var person = new Person();
person.ArbitraryQualifier  = new OtherQualifier();
现在没有最小质量常数

基本原则是,99%的时间里,除了声明对象的类型之外,我们不想知道任何关于该对象的信息。如果属性的声明类型是IArbitraryQualifier,那么该接口的成员就是最重要的。我们不想知道该接口实现的细节,比如其他属性、方法、常量等

一些可能的解决方案:

把常数放在其他地方,也许在Person类中。ArbitraryQualifier不使用常量,那么为什么它需要包含常量呢?这将是我的第一选择。将常数放入需要它的类中。 将属性类型从IArbitraryQualifier更改为ArbitraryQualifier。如果你知道你需要处理这个特殊的类,包括它的常量,那么就使用它。 最不可取的:向IArbitraryQualifier接口添加公共属性,以便所有实现都具有该属性。在这种情况下,这似乎没有任何意义,除非有某种原因说明IArbitraryQualifier的实现必须提供该值。 然而,这并不能解释问题存在的原因

问题的存在是因为您的属性:

public IArbitraryQualifier ArbitraryQualifier { get; }
与具体类的名称相同:

public class ArbitraryQualifier
由于代码包含在Person类中,编译器将把名称解析为local=this local Scoped variables var。。。etc,然后是本地字段/属性,然后是当前命名空间中可访问的命名类,然后是命名空间链的上游

重命名本地/此类上的属性名称也可以解决此问题

public interface IArbitraryQualifier
{
    int Qualification
    {
        get;
    }
}

public class ArbitraryQualifier : IArbitraryQualifier
{
    public const int MIN_QUALITY = 1;
    public int Qualification
    {
        get;
    }
}

public class Person
{
    public IArbitraryQualifier ArbitraryQualifier2
    {
        get;
    }

    public bool AmIARealBoy
    {
        get
        {
            return this.ArbitraryQualifier2.Qualification >= ArbitraryQualifier.MIN_QUALITY;
        }
    }
}

使用它的完全限定名,即Namespace.ClassName.PropertyName。使用此选项将引用您的本地实例。相关:也不是一个好主意
public class ArbitraryQualifier
public interface IArbitraryQualifier
{
    int Qualification
    {
        get;
    }
}

public class ArbitraryQualifier : IArbitraryQualifier
{
    public const int MIN_QUALITY = 1;
    public int Qualification
    {
        get;
    }
}

public class Person
{
    public IArbitraryQualifier ArbitraryQualifier2
    {
        get;
    }

    public bool AmIARealBoy
    {
        get
        {
            return this.ArbitraryQualifier2.Qualification >= ArbitraryQualifier.MIN_QUALITY;
        }
    }
}