0

I need to access a const class value in an instance of that class, without knowing the type of the class, and also be able to access it on the class itself. How can I do this?

Example of what I want to achieve:

public abstract class A { }

public class B : A
{
    public const int X = 50;
}
...
A b = new B();
b.X ???

This is very incomplete, but what I want to achieve is access B's X constant from a variable of type A, through polymorphism (if that makes sense).

This is one way I tried to achieve this:

public abstract class A
{
    public abstract int X { get; }
}

public class B : A
{
    public const int X = 50;
    public override int X { get { return B.X; } } // or return 50;
}

The problem with this though is that C# won't let this compile because of the duplicate definition of X in B. So how should I do this? Is there a better way? Or my only option is to name them differently?

Sh4rK
  • 1
  • 2
  • What is wrong with the `public override int X {...` approach? if you use `{ get { return 50; }}` it works. – MAV May 15 '13 at 23:24
  • @MAV No, it doesn't work because of the multiple definitions of X in B. – Sh4rK May 15 '13 at 23:26
  • You should remove `public const int X = 50;` and just have the override. – MAV May 15 '13 at 23:27
  • Yeah, I'm not sure why you feel the need to have the const value. Is that an imposed requirement of some sort? – itsme86 May 15 '13 at 23:28
  • I need to have the value on the class too, so I can access it like B.X. – Sh4rK May 15 '13 at 23:30
  • @Sh4rK I don't think it is possible to force classes to implement a constant like that. See [this](http://stackoverflow.com/a/3477090/1401257) answer. – MAV May 15 '13 at 23:34
  • The point is not forcing them to implement constants, but to have constants and instace variables of the same name. – Sh4rK May 15 '13 at 23:56
  • Do you need to update the value of X? if yes, choose the static field solution. If you just want the constant, your code works like. `int xvalue = B.X;` and you don't need variable of any type, a const is a const. – terry May 16 '13 at 00:56

2 Answers2

0

Something like this ought to do you:

abstract class A
{
    public abstract int X { get ; }
}

class B : A
{
    public override int X { get { return 5 ; } }
}

By specifying the property as abstract, you force subclasses to implement the readonly property. While there's no way in the type system to require that concrete implementations implement the abstract property such that its value is invariant, presumably your concrete implementations will voluntarily adhere to the specification.

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
  • As I wrote in other comments, I have to be able to access X on the B class itself. – Sh4rK May 16 '13 at 00:05
  • @Sh4rK: What do you mean by *access X on the B class itself*? As `ClassNameB.X`? – Ken Kin May 16 '13 at 00:08
  • @KenKin Yes, like a static variable or a constant. – Sh4rK May 16 '13 at 00:09
  • @Sh4rK: So you don't want to have `X` accessed with an instance? – Ken Kin May 16 '13 at 00:15
  • @KenKin I want to be able to access X both with an instance, and without one. – Sh4rK May 16 '13 at 00:20
  • @Sh4rK...in that case you are SOL. A member can't be both a class member (static) *and* an instance member. Instance methods can reference static members, but static members can't reference instance members. You could probably use reflection to get at the behaviour you want, but that seems...suboptimal. What exactly is the problem you're trying to solve? – Nicholas Carey May 16 '13 at 17:08
0

What you want might be a static readonly member:

public abstract class A {
    public static readonly int X=100;
}

public class B: A {
    public static readonly int X=50;
}

Have a look of readonly. You can think a static readonly member a runtime constant.

If you are looking for an overridable constant/static membe, then you might want to take a look of How to implement virtual static properties?; which is not even possible in C#.

Community
  • 1
  • 1
Ken Kin
  • 4,503
  • 3
  • 38
  • 76
  • @Sh4rK: Do you mean that you want to have all of `A.X` and `a.X` and `B.X` and `b.X` where X exists either with a class or an instance, and apply to both classes? – Ken Kin May 16 '13 at 00:24
  • No, I want `B.X`, and with an instance of B, `b.X` and `a.X`. – Sh4rK May 16 '13 at 00:27
  • @Sh4rK: `B.X` and `b.X` are different; you cannot define an instance member with the same name of a non-instance member. – Ken Kin May 16 '13 at 00:31
  • I'll look for another solution then – Sh4rK May 16 '13 at 00:37
  • @Sh4rK: Simply give them different names and try not to do a workaround. This problem indicates you encountered a bad practice of designing. – Ken Kin May 16 '13 at 00:39