[.net] Another weird c# questions (Is this possible?)

Started by
7 comments, last by Digibo 17 years, 11 months ago
You guys did great with my last one, so here's another I can't figure out. My example:

    class foo
    {
        public static int value = 1;

        public int Value
        {
            get { return value; }
        }
    }

    class fooBar : foo
    {
        new public static int value = 2;
    }

Now I test this: foo one = new foo(); fooBar two = new fooBar(); Assert.AreEqual(1, one.Value); Assert.AreEqual(2, two.Value); <- FAILS, Value == 1 I am guessing that the base class is unaware that the derived class overwrites the value parameter. Is there some way to tell it, so that the proper value is returned?
Advertisement

class foo    {        public static int value;        public foo        {            value = 1;        }        public int Value        {            get { return value; }        }    }    class fooBar : foo    {                public fooBar        {           value = 2;        }    }



This will do what you want it to.

theTroll
This will get his asserts to pass, but i'm fairly sure thats not all he wants.

A simple thing that would pass the tests, would be
class foo{    public virtual int Value    {        get { return 1; }    }}class fooBar : foo{    public override int Value    {        get { return 2; }    }}


If the static member is actually desirable,
class foo{    private static int value = 1;    public virtual int Value    {        get { return value; }    }}class fooBar : foo{    private static new int value = 2;    public override int Value    {        get { return value; }    }}


I will note, in passing, that virtual and override (and abstract, which isnt used here) are only valid on non-static members.

Under TheTroll's suggestion, the assert sequence:

Assert.AreEqual(1, one.Value);
Assert.AreEqual(2, two.Value);
Assert.AreEqual(1, one.Value); <-- fails, value = 2

fails, which is probably undesirable.
Yes the static members are definitley needed. I'm aware of the solution to override the Value method. I was just hoping that there would be a way of solving this problem without having to modify fooBar. Now all of my classes that derive from foo need to override this, and I was really hoping to avoid that.
Don't do this.
    class foo {        public static int InternalValue = 1;                    public int Value {            get {                return ((int)GetType().GetField("InternalValue").GetValue(this));            }        }    }    class foo2:foo{        public static int InternalValue = 2;    }    class Program {        static void Main(string[] args) {            foo a, b;            a = new foo();            b = new foo2();            Console.WriteLine("{0} : {1}", a.Value, b.Value);        }    }


Use Ytinasni's first or move the typeID sort of setup into the garbage bin or a dedicated class rather than with the type.
If the aim is to allow others to extend your class and provide only the static field, you might want to look at the reflection facilities (System.Reflection namespace). I will warn you, this tends to be somewhat not-fast :)

eg:
class MyAttribute{	public readonly int value;	public MyAttribute( int value )	{		this.value = value;	}}[MyAttribute( 1 )]class Foo{	static int GetValueOfValueField( Type type )	{		// error checking omited for clarity		Attribute[] attribs = type.GetCustomAttributes( typeof( MyAttribute ), true );		return (int)( attribs[ 0 ] as MyAttribute ).value;	}	// stuff...}[MyAttribute( 2 )]class FooBar : Foo{	// stuff...}

This does require that your 'value's dont change and are known at complie time though.

Personally, i'd use something similar to my first example, where subclassers override a virtual property only. This does require an instance of the subtype to be created though, which may or may not matter to you.
I'll look into refactoring some thing so that I don't need the static type, otherwise I'll just have to override Value.

Thanks

(It is cool to know that it can be done though, even if it's a bit of a hack.)
I was being dumb.. try this.

class foo    {        public static int value  = 0;        public foo        {            if (value == 0)               value = 1;        }        public int Value        {            get { return value; }        }    }    class fooBar : foo    {                public fooBar        {           if (value == 0)              value = 2;        }    }



Of course the Foo constructor was also getting called, this was overwriting the value set in FooBar. By checking if value is set then you will keep this from happening.

theTroll
If you set it in the constructor and you try this:

foo one = new foo();
fooBar two = new fooBar();

Assert.AreEqual(1, one.Value);
Assert.AreEqual(2, two.Value); <-- fails, value = 1

You still fail, because foo's constructor sets value to 1 and fooBar's constructor never sets it to 2.

Right?

This topic is closed to new replies.

Advertisement