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