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

时间:2014-10-30 23:20:35

标签: c#

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,而不是它自己的对象。 / p>

解决方法是做

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

但如果您有许多Base

子类,这似乎很愚蠢且不可行

<小时/>

解决方案

我最终使用readonly代替const,如下所示:

public readonly int type = 0;

2 个答案:

答案 0 :(得分:10)

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

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

答案 1 :(得分:3)

如果你只是想通过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()]);
}

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