Calling a method on a generic type?

24 views
Skip to first unread message

Philip_L

unread,
Apr 12, 2009, 1:10:56 AM4/12/09
to mono-cecil
If I have a Singleton class that looks like this:

public interface ICreate<T>
{
T Create();
}

public sealed class Singleton<TFactory, T>
where TFactory : ICreate<T>, new()
{
Singleton()
{
}

public static T Instance
{
get
{
return Nested.instance;
}
}

class Nested
{
static Nested()
{
}

internal static readonly T instance = new TFactory().Create
();
}
}

How do I actually get a MemberReference to the static Instance
property so I can call the get_Instance method?

This is the code that I have so far:

var genericSingletonType = module.Import(typeof
(Singleton<,>));
var singletonType = new GenericInstanceType
(genericSingletonType);
singletonType.GenericArguments.Add(creatorType);
singletonType.GenericArguments.Add(itemType);

The problem is that since the singletonType is actually a
GenericInstanceType, I can't seem to access the get_Instance method
(or frankly, I'm not sure where to access it). What makes this even
more confusing is that when I look at the operand of a compiler-
emitted Call instruction to the Singleton<TFactory, T>.Instance
property, it lists the get_Instance method as a MemberReference. So my
question is this: How do I emit a call to the instantiated
Singleton<TFactory, T>.get_Instance method? Thanks in advance for your
help!

Philip_L

unread,
Apr 12, 2009, 3:51:12 AM4/12/09
to mono-cecil
Here's the updated code that I'm using to emit the Singleton<,> call:

// Call the Singelton<TFactory, TService>.Instance
var genericSingletonType = module.Import(typeof
(Singleton<,>));
var serviceTypeParameter =
genericSingletonType.GenericParameters[1];

var singletonType = new GenericInstanceType
(genericSingletonType);
singletonType.GenericArguments.Add(creatorType);
singletonType.GenericArguments.Add(serviceType);

var getInstanceMethod = new MethodReference
("get_Instance", singletonType, serviceTypeParameter, false, false,
MethodCallingConvention.Default);
module.MemberReferences.Add(getInstanceMethod);

IL.Emit(OpCodes.Call, getInstanceMethod);

The problem is that PEVerify keeps reporting "Unable to resolve
token". Is there something that I'm doing wrong here?

Lotfi Gheribi

unread,
Apr 12, 2009, 4:22:14 PM4/12/09
to mono-...@googlegroups.com
> // Call the Singelton<TFactory, TService>.Instance
>            var genericSingletonType = module.Import(typeof
> (Singleton<,>));

I don't know why, but it seams that the Import method doesn't import
generic parameter constraints :s

var genericSingletonType = module.Import(typeof(Singleton<,>));

Philip Laureano

unread,
Apr 12, 2009, 9:31:46 PM4/12/09
to mono-...@googlegroups.com
I never managed to solve the bug--instead, I ended up emitting a whole
non-generic singleton class implementation. It wasn't pretty, but it
definitely worked :)
Reply all
Reply to author
Forward
0 new messages