Why can't I access a constant from an object?

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

Why can't i do this? Is there a reason behind it or am I trying to access the constant in a wrong way?

new Foo().type;

I know I can do Foo.type but given my scenario, I cant do that. For example if I have two class which inherit from a base class like this:

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

I would want to get the type property of the class sent through the printType() function but I cant since I can only access the type from the Class, not the object its self.

A work around would be to do

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

but this seems stupid and not viable if you have many sub classes of Base


Solution

I ended up using readonly instead of const like this:

public readonly int type = 0;
Jon Skeet
people
quotationmark

Yes, you're trying to access it in the wrong way. A constant isn't associated with an instance of a type - it's associated with the type itself. So you want:

int x = Foo.type;

Basically, const members are implicitly static, and C# doesn't let you access static members as if they were instance members, via a value. (Note that in .NET naming conventions, it should be Type rather than type.)

EDIT: Now that you've explained the actual situation, it appears you're trying to use polymorphism, which won't work for constants. So instead, you should have an abstract property in the base class, implemented in subclasses.

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

Alternatively, just have a normal property in the base class which is populated via the base class constructor:

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

people

See more on this question at Stackoverflow