为什么我不能从对象访问常量

本文关键字:访问 常量 对象 不能 为什么 | 更新日期: 2023-09-27 18:28:43

public class Foo
{
    public const int type = 1;
}

为什么我不能这样做?这背后是有原因的,还是我试图以错误的方式访问常量?

new Foo().type;

我知道我可以做Foo.type但考虑到我的情况,我不能那样做。例如,如果我有两个从基类继承的类,如下所示:

public class Base
{
    ...
}
public class Foo : Base
{
    public const int type = 0;
}
public class Bar : Base
{
    public const int type = 1;
}
public static void printType(Base b)
{
     Console.WriteLine(b.type);
}

我想获取通过 printType(( 函数发送的类的 type 属性,但我不能,因为我只能从类访问type,而不是对象本身。

解决方法是要做

if(b is Foo){
    Console.Write(Foo.type);
}elseif....

但是,如果您有许多子类Base,这似乎很愚蠢且不可行


溶液

我最终使用了readonly而不是像这样的const

public readonly int type = 0;

为什么我不能从对象访问常量

是的,您试图以错误的方式访问它。常量不与类型的实例关联 - 它与类型本身相关联。所以你想要:

int x = Foo.type;

基本上,const成员是隐式静态的,C# 不允许你通过值访问静态成员,就好像它们是实例成员一样。(请注意,在 .NET 命名约定中,它应该是Type而不是type

编辑:现在您已经解释了实际情况,您似乎正在尝试使用多态性,这不适用于常量。因此,您应该在基类中有一个抽象属性,在子类中实现。

public abstract class Base
{
    public abstract int Type { get; }
}
public class Foo : Base
{
    public override int Type { get { return 0; } }
}
public class Bar : Base
{
    public override int Type { get { return 0; } }
}

或者,只需在基类中有一个普通属性,该属性通过基类构造函数填充:

public class Base
{
    private readonly int type;
    public int Type { get { return type; } }
    protected Base(int type)
    {
        this.type = type;
    }
}
public class Foo : Base
{
    public Foo() : base(0) {}
}
public class Bar : Base
{
    public Bar() : base(1) {}
}

如果你只想标识传入对象的动态(派生最多(类型,则通过 Object.GetType() 方法将其内置到 .NET 中。

public static void printType(Base b)
{
     Console.WriteLine(b.GetType().Name);
}

当然,这与在您的控制下附加数据并不完全相同。 但是,您可以使用Dictionary<Type, T>将任意类型的数据与各种子类相关联。 使用子类类型初始值设定项将新条目安装到此类字典中是合理的。

public class Base
{
    static internal readonly Dictionary<System.Type, int> TypeMap =
       new Dictionary<System.Type, int>();
}
public class Foo : Base
{
    static Foo { TypeMap.Add(typeof(Foo), 0); }
}
public class Bar : Base
{
    static Bar { TypeMap.Add(typeof(Bar), 1); }
}
public static void printType(Base b)
{
     Console.WriteLine(Base.TypeMap[b.GetType()]);
}

这将比每个对象字段的方法慢一点,但它不会为每个对象添加任何额外的存储空间。