By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,672 Members | 1,644 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,672 IT Pros & Developers. It's quick & easy.

"Override" static method via DynamicMethod

P: n/a
I'd like to create a new static property in a class "hiding" the
property present in a base class. Since this needs to happen at runtime
I tried doing this via DynamicMethod. But obviously the created methods
are not "registered" and only available through the DynamicMethod class.
So a method lookup finds the origin property.

A little test:

public class DerivedClass : BaseClass
{
public static DynamicMethod CustomMethod;
}

public class BaseClass
{
public static int Something
{
get
{
return 5;
}
}

public static void Main(string[] args)
{
DerivedClass.CustomMethod = new
System.Reflection.Emit.DynamicMethod("get_Somethin g",
MethodAttributes.NewSlot | MethodAttributes.Static |
MethodAttributes.Public, CallingConventions.Standard, typeof(int), null,
typeof(DerivedClass), false);
ILGenerator generator = DerivedClass.CustomMethod.GetILGenerator();

generator.Emit(OpCodes.Ldc_I4, 3);
generator.Emit(OpCodes.Ret);

Console.WriteLine("BaseClass: " + Something.ToString() + "
DerivedClass: " + DerivedClass.Something.ToString());
}
}

Currently gives BaseClass: 5 DerivedClass: 5.
I'd like it to give me BaseClass: 5 DerivedClass: 3.
(How) can this be achived?

Regards
LCID Fire
Oct 7 '06 #1
Share this Question
Share on Google+
5 Replies


P: n/a
<none <""lcid-fire\"@(none)">wrote:
I'd like to create a new static property in a class "hiding" the
property present in a base class. Since this needs to happen at runtime
I tried doing this via DynamicMethod. But obviously the created methods
are not "registered" and only available through the DynamicMethod class.
So a method lookup finds the origin property.
You've got bigger problems than that - if you decompile the IL, you'll
find that because DerivedClass doesn't have a Something property at
compile-time, the call to DerivedClass.Something is actually compiled
directly into a call to BaseClass.Something.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Oct 7 '06 #2

P: n/a
Jon Skeet [C# MVP] wrote:
<none <""lcid-fire\"@(none)">wrote:
>I'd like to create a new static property in a class "hiding" the
property present in a base class. Since this needs to happen at runtime
I tried doing this via DynamicMethod. But obviously the created methods
are not "registered" and only available through the DynamicMethod class.
So a method lookup finds the origin property.

You've got bigger problems than that - if you decompile the IL, you'll
find that because DerivedClass doesn't have a Something property at
compile-time, the call to DerivedClass.Something is actually compiled
directly into a call to BaseClass.Something.
Ok, aside from the question whether statics should derive from base
classes one could restructure the code to:

public class DerivedClass : BaseClass
{
public static DynamicMethod _dc;
}

public class BaseClass
{
public virtual int get_Something()
{
return 5;
}

public static void Main(string[] args)
{
DerivedClass._dc = new
System.Reflection.Emit.DynamicMethod("get_Somethin g",
MethodAttributes.Public, CallingConventions.Standard, typeof(int), null,
typeof(DerivedClass), false);
ILGenerator generator = DerivedClass._dc.GetILGenerator();

generator.Emit(OpCodes.Ldc_I4, 3);
generator.Emit(OpCodes.Ret);

Console.WriteLine("BaseClass: " + new
BaseClass().get_Something().ToString() + " DerivedClass: " + new
DerivedClass().get_Something().ToString());
}
}

Nevertheless it doesn't work. What am I doing wrong?
Oct 7 '06 #3

P: n/a
"none" <""lcid-fire\"@(none)"a écrit dans le message de news:
eD**************@TK2MSFTNGP05.phx.gbl...

| Ok, aside from the question whether statics should derive from base
| classes one could restructure the code to:

Static methods belong to the class in which they are declared, you have to
declare another method of the same type in the derived class in order to get
different behaviour :

public class BaseClass
{
public static int get_Something()
{
return 5;
}
}

public class DerivedClass : BaseClass
{
public static int get_Something()
{
return 3;
}
}

And you really don't need LCG or dynamic methods to call the appropriate
static method :

public int GetInt<T>() where T : BaseClass
{
Type type = typeof(T);

MethodInfo mi = type.GetMethod("get_Something", BindingFlags.Public |
BindingFlags.Static);

return (int) mi.Invoke(null, null);
}

.... and this method gets called like this :

{
// either
int i = GetInt<BaseClass>();

// or

int i = GetInt<DerivedClass>();
}

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Oct 8 '06 #4

P: n/a
Joanna Carter [TeamB] wrote:
"none" <""lcid-fire\"@(none)"a écrit dans le message de news:
eD**************@TK2MSFTNGP05.phx.gbl...

| Ok, aside from the question whether statics should derive from base
| classes one could restructure the code to:

Static methods belong to the class in which they are declared, you have to
declare another method of the same type in the derived class in order to get
different behaviour :
Ok, but what I don't see is why the clr cannot search for the "highest"
implementation of a static method. You have the derivance, even if you
don't have a class instance yet.
And you really don't need LCG or dynamic methods to call the appropriate
static method :
That's my problem. I definately don't know at compile time, which value
I want to override. This is all taken out of xml files.
So I read in the xml files and want to change some initial values.

Would this be possible if I create a temporarily copy of each type and
change this via the TypeBuilder (something similar to the page handling
in ASP.NET)?

public int GetInt<T>() where T : BaseClass
{
Type type = typeof(T);

MethodInfo mi = type.GetMethod("get_Something", BindingFlags.Public |
BindingFlags.Static);

return (int) mi.Invoke(null, null);
}
Thanks for the hint. Doing a typeof(T) didn't cross my mind so far. I
could use something on some other code.
Oct 8 '06 #5

P: n/a
"none" <""lcid-fire\"@(none)"a écrit dans le message de news:
e8*************@TK2MSFTNGP05.phx.gbl...

| Ok, but what I don't see is why the clr cannot search for the "highest"
| implementation of a static method. You have the derivance, even if you
| don't have a class instance yet.

I think what you are after is a feature like Delphi class references, which
facilitate virtual constructors and virtual static methods. This is
something that can be emulated by designing a "metaclass".

A metaclass is usually designed as nested class within the base class, that
can only be instantiated through a static method of the base class, but that
possesses virtual instance methods that call the correct constructor or
static method on a given derived type using similar techniques to the method
I gave as an example.

public class ClassReference<T>
{
public T Create<U>() where U : T
{
// code to call default constructor on U
}

protected T Create<U>(object[] ctorArgs) where U : T
{
// code to call parameterised constructor on U
}
}

public class Base
{
public class ClassReference : ClassReference<Base>
{
public Base Create<U>() where U : Base
{
return base.Create<U>();
}

public Base Create<U>(int value) where U : Base
{
return base.Create<U>(new object[] { value });
}

// additional "virtual static" method
public int GetValue<U>() where U : T
{
Type type = typeof(U);

MethodInfo mi = type.GetMethod("GetValue", BindingFlags.Public |
BindingFlags.Static);

return (int) mi.Invoke(null, null);
}
}

public static ClassReference ClassRef
{
get { return new ClassReference(); }
}

private int value;

public Base() : this(0) { }

public Base(int value)
{
this.value = value;
}

public static int GetValue()
{
return 5;
}
}

public class Derived : Base
{
public Derived() : base() { }

public Derived(int value) : base(value) { }

public static new int GetValue()
{
return 3;
}
}

Used like this :

{
Base.ClassReference cr = Base.ClassRef;

Base b = cr.Create<Derived>();

int i = cr.GetValue<Base>();

// or

int i = cr.GetValue<Derived>();
}

| That's my problem. I definately don't know at compile time, which value
| I want to override. This is all taken out of xml files.
| So I read in the xml files and want to change some initial values.

Then modify the metaclass idea to take a Type parameter instead of a generic
parameter, and use Type GetType(string) to get the type to pass in.

{
Base.ClassReference cr = Base.ClassRef;

Type derivedType = Type.GetType("Derived");

Base b = cr.Create(derivedType);

int i = cr.GetValue(typeof(Base));

// or

int i = cr.GetValue(derivedType);
}

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Oct 8 '06 #6

This discussion thread is closed

Replies have been disabled for this discussion.