Function returning a generic type whose value is known only at runtime?

Typeof(IContainer). MakeGenericType(type) will only evaluate at runtime, while "as" needs to know the type at compiler time What I really don't understand is this comment: My problem is that I don't know how to enumerate the result which has type Object (therefore I cannot cast it to IEnumerable) myContainer may be an Object but it can surely be cast to IEnumerable? If it can't then it can't be enumerated.

Typeof(IContainer). MakeGenericType(type) will only evaluate at runtime, while "as" needs to know the type at compiler time. What I really don't understand is this comment: My problem is that I don't know how to enumerate the result which has type Object (therefore I cannot cast it to IEnumerable).

MyContainer may be an Object but it can surely be cast to IEnumerable? If it can't then it can't be enumerated.

Thank you, I had overlooked the fact that IContainer (despite its name) actually does not implement IEnumerable. That's why the cast was failing. Your comment got me on the right track to solve my issue.

– Stefano Ricciardi Feb 18 '10 at 16:23.

Your type T must be known by the compiler, so this will not work. You can try making a non generic version of your interface, like this: public interface IContainer { IEnumerable Contents { get; } } public interface IContainer : IContainer { ... } This way you have something to cast to and are able to use it.

First, when casting you need a type (double, int); typeof takes a type argument and returns a class of type Type. Object x = 0.0; Type t = typeof(double); double y = x as t; //does not compile - t is not a type - it's an instance of type Type double y = x as typeof(double); //same as above double y = x as double; //compiles - double is a type Type z = x as Type; //compiles - Type is a type Second, here is some example code: using System; using System.Collections. Generic; using System.

Collections; using System. Reflection; using System. Diagnostics; namespace TryThis { public interface IContainer { IEnumerable Contents { get; } } public interface IContent { T GetMyContent(); } public interface IProperty { } public class Content : IContent { T m_content = default(T); public T GetMyContent() { return m_content; } public Content(T val) { m_content = val; } } public class Contents : IEnumerable { List m_contents = new List(); IEnumerator IEnumerable.GetEnumerator() { return m_contents.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return m_contents.GetEnumerator(); } public Contents(params T contents) { foreach (T item in contents) m_contents.

Add(new Content(item)); } } public class TestGenericContent : IContainer { public IContainer GetContainer(IProperty property) { return this; } public IEnumerable Contents { get { return new Contents(1, 2, 3); } } } public static class TryThisOut { static void Test2(object o) { Type t = o.GetType(); Type tInterface = t. GetInterface("IContainer`1"); //could be null if o does not implement IContainer Type tGenericArg = tInterface. GetGenericArguments()0; //extracts T from IContainer MethodInfo info = t.

GetMethod("GetContainer"); IProperty propArg = null; //null in this example object oContainer = info. Invoke(o, new object { propArg }); PropertyInfo prop = tInterface. GetProperty("Contents"); object oContents = prop.GetGetMethod().

Invoke(oContainer, null); //oContents is of type IEnumerable, which derives from IEnumerable, so we can cast IEnumerable enumeratedContents = oContents as IEnumerable; MethodInfo getContentItem = typeof(IContent). MakeGenericType(tGenericArg). GetMethod("GetMyContent"); foreach (object item in enumeratedContents) { object oContentItem = getContentItem.

Invoke(item, null); Debug. Print("Item {0} of type {1}", oContentItem, oContentItem.GetType()); //... } } public static void Test() { object o = new TestGenericContent(); Test2(o); } } }.

If you're thinking of moving to . Net 4 that is what the dynamic type provides.

Unfortunately I cannot make such an assumption because my code is part of a library that might be reused. While I know that mostly strings, doubles and decimals will be handled, I cannot exclude other types "a priori". If all else fails, though, I might have to go that route and raise exceptions for unexpected types.

– Stefano Ricciardi Feb 18 '10 at 8:21 @Stefano - test your object type against IEnumerable that way you can ensure that you only cast it e.g. For use in a foreach statement, if your object class inherits IEnumerable. – ChrisBD Feb 18 '10 at 9:35.

Sorry if I misunderstood, I was having trouble understanding exactly what your objective was. Were you looking for something like this? Var myContainer = typeof(ClassWithGetContainer) .

GetMethod("GetContainer") . MakeGenericMethod(runtimeType) . Invoke(InstanceOfClassWithGetContainer, new object { property }).

No, I am already past this point. I have already populated myContainer and it's working. My problem comes afterward, that is retrieving the single contents from the container.

– Stefano Ricciardi Feb 18 '10 at 8:19.

Type tInterface = t. Type tGenericArg = tInterface. MethodInfo info = t.

Object oContainer = info.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions