Make a castable type from GetType? - c#

Explained below in the code snippet, I can't figure out the syntax for this:
object tcsObject = new TaskCompletionSource<Apple>();
Apple apple = new Apple();
// How do I do this?
TaskCompletionSource<apple.GetType>() tsc = tscObject as TaskCompletionSource<apple.GetType>()
edit
Should note the particular issue I am trying to figure is how to do this generics cast without initially knowing that the the type is Apple. The type could end up being anything, so I am looking to do this operation from what is returned via GetType.

If you don't mind sacrificing compile-time type safety, you could make use of Convert.ChangeType() and the dynamic keyword like so:
static dynamic ConvertTo(this object source, Type targetType)
{
return (dynamic)Convert.ChangeType(source, targetType)
}
public void YourActualCode()
{
object tcsObject = new TaskCompletionSource<Apple>();
Apple apple = new Apple();
TaskCompletionSource<Apple> tsc = ConvertTo(tscObject, typeof(TaskCompletionSource<Apple>))
}
The nice thing about this approach is you can defer determination of the parameter type until runtime:
var wrapperType = typeof(TaskCompletionSource<>);
var paramType = typeof(Apple);
var concreteType = wrapperType.MakeGenericType(paramType);
TaskCompletionSource<Apple> tsc = ConvertTo(tscObject, concreteType);

Related

C# Covert Type into IEnumerable of same Type?

I have some methods that execute arbitrary SQL against a database and serialize that data collection into a list of a concrete type. That data is then serialized into JSON and stored in a cell in a table. Later, I need to come back and deserialize that data back into its original collection so that it can be used.
I'm having some issues figuring out how to take a Type object and create a collection of that type in order to deserialize it. Here is how my code operates:
public async Task ExecuteWidget(Guid runGuid, string widgetName, Type type, string sql,
IEnumerable<SqlParameter> parameters)
{
var report = operationsContext.ReportRuns.FirstOrDefault(n => n.RunGuid == runGuid);
CheckReportStatus(report);
var param = parameters.ToList();
var result = edwContext.Database.SqlQuery(type, sql, param.ToArray<object>());
var query = result.GetQuery(param);
var data = await result.ToListAsync();
var widgetData = new ReportRunWidgetData()
{
ReportRunId = report?.ReportRunId ?? -1, // This should never be null.
WidgetName = widgetName,
WidgetData = new JavaScriptSerializer().Serialize(data),
Query = query
};
operationsContext.ReportRunWidgetDatas.Add(widgetData);
await operationsContext.SaveChangesAsync();
}
My fetching logic looks something like this:
public object FetchWidgetData(Guid runGuid, string widgetName, Type dataType)
{
var data = operationsContext.ReportRuns
.Include("ReportRunWidgetDatas")
.FirstOrDefault(n => n.RunGuid == runGuid)?
.ReportRunWidgetDatas.FirstOrDefault(n => n.WidgetName == widgetName)?
.WidgetData;
if (data == null) return null;
var deserialized = new JavaScriptSerializer().Deserialize(data, dataType);
return deserialized;
}
Now when the ExecuteWidget method is called, the type parameter is populated by the widget's DTO datatype. For example HeadlineWidgetDTO. However, the execute command gets the data back as a List<HeadlineWidgetDTO>. When my FetchWidgetData method is called, the dataType supplied is still HeadlineWidgetDTO, but it actually needs to be of type IEnumerable<HeadlineWidgetDTO> to deserialize properly.
Given just the type for an individual data row, how can I create a Type object that is instead a collection of that type?
This is mostly a duplicate of How to use Activator to create an instance of a generic Type and casting it back to that type?, however it's hard to tell.
Basically, if you have a type object Type theType, you need to do something like:
var listType = typeof(List<>);
var typeParams = new [] {theType};
var listOfTType = listType.MakeGenericType(typeParams);
var newListOfT = Activator.CreateInstance(listOfTType);
At that point, you have a variable of type object, but that references an object of type List<WhateverYourTypeIs>. Say, theType is typeof(int), then you will have an object of List<int>. Casting it to something usuable is a whole other question though. If you want to add something to that list, I suspect the best way would be to get a MethodInfo for the Add method and Invoke it.
I thought of another way to do this if the type has a default constructor and isn't too expensive to create. Here's a sample (creating a List<int> - but that's just the way I have it coded):
var type = typeof(int);
var dummy = Activator.CreateInstance(type);
var listOfType = new[] {dummy}.ToList();
When you are finished, the listOfType variable is typed as a List<object> but refers to a List<int>. It's mostly mostly workable - for example, you can call Add(object someObj) on it. You won't get compile type parameter type checking, but you will be able to use it.

'type' is a variable but is used like a type [duplicate]

The following doesn't work, of course. Is there a possible way, which is pretty similar like this?
Type newObjectType = typeof(MyClass);
var newObject = givenObject as newObjectType;
newObjectType is an instance of the Type class (containing metadata about the type) not the type itself.
This should work
var newObject = givenObject as MyClass;
OR
var newObject = (MyClass) givenObject;
Casting to an instance of a type really does not make sense since compile time has to know what the variable type should be while instance of a type is a runtime concept.
The only way var can work is that the type of the variable is known at compile-time.
UPDATE
Casting generally is a compile-time concept, i.e. you have to know the type at compile-time.
Type Conversion is a runtime concept.
UPDATE 2
If you need to make a call using a variable of the type and you do not know the type at compile time, you can use reflection: use Invoke method of the MethodInfo on the type instance.
object myString = "Ali";
Type type = myString.GetType();
MethodInfo methodInfo = type.GetMethods().Where(m=>m.Name == "ToUpper").First();
object invoked = methodInfo.Invoke(myString, null);
Console.WriteLine(invoked);
Console.ReadLine();
You can check if the type is present with IsAssignableFrom
if(givenObject.GetType().IsAssignableFrom(newObjectType))
But you can't use var here because type isn't known at compile time.
I recently had the case, that I needed to generate some code like in Tomislav's answer. Unfortunately during generation time the type T was unknown. However, a variable containing an instance of that type was known. A solution dirty hack/ workaround for that problem would be:
public void CastToMyType<T>(T hackToInferNeededType, object givenObject) where T : class
{
var newObject = givenObject as T;
}
Then this can be called by CastToMyType(instanceOfNeededType, givenObject) and let the compiler infer T.
You can use Convert.ChangeType. According to msdn, it
returns an object of a specified type whose value is equivalent to a
specified object.
You could try the code below:
Type newObjectType = typeof(MyClass);
var newObject = Convert.ChangeType(givenObject, newObjectType);
Maybe you can solve this using generics.
public void CastToMyType<T>(object givenObject) where T : class
{
var newObject = givenObject as T;
}

How to get typeof(List<>) from typeof(List<T>) by removing generic argument

I have typeof(List<T>) as a Type object, but I need the typeof(List<>) from which I can use MakeGenericType() to retrieve a type object for List, is it possible?
Update: Guys, thx. This seems a trivial question. But anyway, I upvoted everyone and accepted the first answer.
If I undestand your problem correctly, you have a generic type (List<int>) and another type (lets say long) and you want to make a List<long>. That can be done like this:
Type startType = listInt.GetType(); // List<int>
Type genericType = startType.GetGenericTypeDefinition() //List<T>
Type targetType = genericType.MakeGenericType(secondType) // List<long>
However, if the types you are working with are indeed lists, it might be clearer if you actually used:
Type targetType = typeof(List<>).MakeGenericType(secondType) // List<long>
You can use Type.GetGenericTypeDefinition.
I assume you mean to achieve something like the below?
var list = new List<int>();
Type intListType = list.GetType();
Type genericListType = intListType.GetGenericTypeDefinition();
Type objectListType = genericListType.MakeGenericType(typeof(object));
The answer is Type.GetGenericTypeDefinition:
http://msdn.microsoft.com/en-us/library/system.type.getgenerictypedefinition.aspx
Example:
var t = typeof(List<string>);
var t2 = t.GetGenericTypeDefinition();
And then could do this:
var t = typeof(List<>);
var t2 = t.MakeGenericType(typeof(string));

Get original type of intercepted object in Unity

How can I get the 'original' type of a proxy object which was intercepted by Unity's VirtualMethodInterceptor?
I've got something like:
T obj = (T)Intercept.NewInstance(typeof(T), new VirtualMethodInterceptor(), new[] { new MyInterceptor() });
then when I ask for the type of obj it will be something like DynamicModule.ns.Wrapped_TheRealType_7615f35579e1442192a7aaf806733b7b
How do I get TheRealType's Type via code?
You can descend the inheritance hierarchy of the generated type until you reach the correct one.
Type original = target.GetType();
while (original.Name.StartsWith("Wrapped_"))
{
original = original.BaseType;
}
Not pretty but it should do the trick.

How to create a Expression.Lambda when a type is not known until runtime?

This is best explained using code. I have a generic class that has a method that returns an integer. Here is a simple version for the purposes of explaining...
public class Gen<T>
{
public int DoSomething(T instance)
{
// Real code does something more interesting!
return 1;
}
}
At runtime I use reflection to discover the type of something and then want to create an instance of my Gen class for that specific type. That is easy enough and done like this...
Type fieldType = // This is the type I have discovered
Type genericType = typeof(Gen<>).MakeGenericType(fieldType);
object genericInstance = Activator.CreateInstance(genericType);
I now want to create an Expression that will take as a parameter an instance of the generic type and then calls the DoSomething method of that type. So I want the Expression to effectively perform this...
int answer = genericInstance.DoSomething(instance);
...except I do not have the 'instance' until some point later at runtime and the genericInstance is the generated type as can be seen above. My attempt at creating the Lambda for this is as follows...
MethodInfo mi = genericType.GetMethod("DoSomething",
BindingFlags.Instance | BindingFlags.Public);
var p1 = Expression.Parameter(genericType, "generic");
var p2 = Expression.Parameter(fieldType, "instance");
var x = Expression.Lambda<Func<genericType, fieldType, int>>
(Expression.Call(p1, mi, p2),
new[] { p1, p2 }).Compile();
...so that later on I can call it with something like this...
int answer = x(genericInstance, instance);
Of course, you cannot provide Func with instance parameters and so I have no idea how to parameterize the Lambda generation. Any ideas?
I think you would just use the Expression.Lambda that takes the delegate type as a type rather then as a generic, and create your Func on the fly like you are with Gen<>:
MethodInfo mi = genericType.GetMethod("DoSomething",
BindingFlags.Instance | BindingFlags.Public);
var p1 = Expression.Parameter(genericType, "generic");
var p2 = Expression.Parameter(fieldType, "instance");
var func = typeof (Func<,,>);
var genericFunc = func.MakeGenericType(genericType, fieldType, typeof(int));
var x = Expression.Lambda(genericFunc, Expression.Call(p1, mi, p2),
new[] { p1, p2 }).Compile();
This will return a Delegate rather than a strongly typed Func, but you can of course cast it if needed (and seemingly difficult if you don't know what you are casting to), or dynamically invoke it using DynamicInvoke on it.
int answer = (int) x.DynamicInvoke(genericInstance, instance);
EDIT:
A good idea that does indeed work. Unfortunately the reason I want to use a strongly typed compiled Lambda is performance. Using DynamicInvoke is prettty slow compared to a typed Lambda.
This seems to work without the need of a dynamic invoke.
var p1 = Expression.Parameter(genericType, "generic");
var p2 = Expression.Parameter(fieldType, "instance");
var func = typeof(Func<,,>);
var genericFunc = func.MakeGenericType(genericType, fieldType, typeof(int));
var x = Expression.Lambda(genericFunc, Expression.Call(p1, mi, p2), new[] { p1, p2 });
var invoke = Expression.Invoke(x, Expression.Constant(genericInstance), Expression.Constant(instance));
var answer = Expression.Lambda<Func<int>>(invoke).Compile()();
EDIT 2:
A greatly simplified version:
Type fieldType = ;// This is the type I have discovered
Type genericType = typeof(Gen<>).MakeGenericType(fieldType);
object genericInstance = Activator.CreateInstance(genericType);
MethodInfo mi = genericType.GetMethod("DoSomething",
BindingFlags.Instance | BindingFlags.Public);
var value = Expression.Constant(instance, fieldType);
var lambda = Expression.Lambda<Func<int>>(Expression.Call(Expression.Constant(genericInstance), mi, value));
var answer = lambda.Compile()();
This answer only applies if you are using .NET 4.0.
If you make genericInstance dynamic instead of object, you can then call the DoSomething method on it directly, and the dynamic language runtime will take care of everything for you.
class Type1 {
public int DoSomething() { return 1; }
}
class Type2 {
public int DoSomething() { return 2; }
}
static void TestDynamic() {
dynamic t1 = Activator.CreateInstance(typeof(Type1));
int answer1 = t1.DoSomething(); // returns 1
dynamic t2 = Activator.CreateInstance(typeof(Type2));
int answer2 = t2.DoSomething(); // returns 2
}
If you need to keep this class structure (Gen<T>), then I don't see an easy way around the fact that you don't know the type T at compile time. If you want to call the delegate, you either have to know its full type at compile time, or you need to pass in the parameters as objects.
Using dynamic gets you to hide the complexity of getting the MethodInfo, etc., and gives you excellent performance. The one drawback vs. DynamicInvoke that I see is that I believe you get the initial overhead of resolving the dynamic call once for every call site. The bindings are cached so that they run very fast from the second time onwards if you call it on objects with the same type.
It's better to to accept an object and use convert to a known type.
Here is an example, how to build access to a property by name on unknown depth:
var model = new { A = new { B = 10L } };
string prop = "A.B";
var parameter = Expression.Parameter(typeof(object));
Func<object, long> expr = (Func<object, long>) Expression.Lambda(prop.Split('.').Aggregate<string, Expression>(Expression.Convert(parameter, model.GetType()), Expression.Property), parameter).Compile();
expr(model).Dump();
It avoids extra costs of DynamicInvoke when type of delegate is unknown at compile time.

Categories