Sign in to follow this  
Ataru

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

Recommended Posts

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?

Share this post


Link to post
Share on other sites


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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.)

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this