1

I get my variable from var pi = propertyInfo.GetValue(instance) this is an object Type. I know all result of this are of type ObjectSet<TEntity> . I don't know TEntity. TEntity is allways different.

The consuming function looks alike:

BuildClassItem<T>(ObjectSet<T> entities, ... ) where T : class

How can I cast object to ObjectSet ?

I tried alredy this. But I don't know T

public static ObjectSet<T> MyConvert<T>(object myInput) where T : class
{
    return (ObjectSet<T>)myInput;
}
flakes
  • 21,558
  • 8
  • 41
  • 88
LWS
  • 329
  • 3
  • 15
  • 3
    _"How can I cast object to ObjectSet ?"_ -- what _exactly_ do you mean by that? In C# "cast" can be a conversion, or a reinterpretation. Reinterpretation would apply only if you are actually _interpreting_ the type in the first place, which would require knowing the type at compile time. Conversion would apply only if you are trying to change the object from one type to another, but there's only one type of relevance in your question. It's not clear at all what it is you think you are doing. – Peter Duniho Sep 04 '19 at 05:35
  • Probably would have to do the whole thing using reflection if you really need the type information present. https://stackoverflow.com/a/1151470/3280538 https://stackoverflow.com/a/3403976/3280538 – flakes Sep 04 '19 at 05:41
  • Are we to assume that `myInput` isn't already an `ObjectSet`, and there's some kind of explicit or implicit cast defined? – ProgrammingLlama Sep 04 '19 at 05:42
  • You cant cast to something you dont know at compile time unless you were to compare it using if statements – TheGeneral Sep 04 '19 at 05:49
  • @John myInput is alredy ObjectSet – LWS Sep 04 '19 at 05:55
  • @LWS Then there's no way you can achieve this if you don't know T. – ProgrammingLlama Sep 04 '19 at 05:55
  • Out of interest, without knowing `T`, how would you hope to use `ObjectSet` if this were in some way possible? – ProgrammingLlama Sep 04 '19 at 06:16
  • When all you know about T is that it's a reference type, you can simply do `ObjectSet`... Not much else, I'm afraid. – Zohar Peled Sep 04 '19 at 06:23
  • 1
    You are saying: it is not working, what is not working, what it the error you get? – Aldert Sep 04 '19 at 07:11
  • @ZoharPeled: While you could do that, the cast would fail the actual type was `ObjectSet` for example. – Jon Skeet Sep 04 '19 at 07:54
  • @JonSkeet Yeah, I forgot about the bawl of apples vs bawl of fruit thing for a minute. – Zohar Peled Sep 04 '19 at 08:00

2 Answers2

1

You can use System.Linq.Expressions to construct a "trampoline" - a call into a method which is generic. Once you're inside that generic method, then you can start using T naturally when you need to talk about the type. Here I'm using BuildClassItem directly as the target for the trampoline:

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace Exercise
{
    class Program
    {

        static void Main(string[] args)
        {
            var obj = GetObjectSet();
            //We know obj is an ObjectSet<T> for unknown T
            var t = obj.GetType().GetGenericArguments()[0];
            var parm = Expression.Parameter(typeof(object));
            var objectSet = typeof(ObjectSet<>).MakeGenericType(t);
            var method = typeof(Program).GetMethod("BuildClassItem", BindingFlags.Static | BindingFlags.NonPublic).MakeGenericMethod(t);

            var trampoline = Expression.Lambda(
                Expression.Call(null, method, Expression.Convert(parm,objectSet)), new[] {parm});
            var dele = (Action<object>) trampoline.Compile();
            dele(obj);
            Console.WriteLine("Done");
            Console.ReadLine();
        }

        static void BuildClassItem<T>(ObjectSet<T> entities) where T : class
        {
            Console.WriteLine("We made it!");
        }

        static object GetObjectSet()
        {
            return new ObjectSet<string>();
        }
    }

    internal class ObjectSet<T> where T:class
    {
    }
}

If you have more work to do between finding the type T and calling BuildClassItem you'd still want to put all of that logic inside a generic method in T and construct a void call into it. You can't "say" the name of the type from outside a generic method so you have no way of storing the returned value from your MyConvert function in a correctly typed variable. So you need to move all of the logic into it.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
  • To simplify casting I asked Microsoft guys to add ? mark symbol for casting https://github.com/dotnet/csharplang/issues/2932 – Denis Kotov Sep 25 '20 at 21:37
0
public class ObjectSet<T>
{
}

public static ObjectSet<T> MyConvert<T>(object myInput) where T : class
{
    return (ObjectSet<T>)myInput;
}

invoke like this :

ObjectSet<object> get =  MyConvert<object>(new ObjectSet<object>());

I'm not got any error , So what error for your case ??

or

public class FOO
{
}
public interface IObjectSet
{
}

public class ObjectSet<T> : IObjectSet
{
}

IObjectSet get =  MyConvert<FOO>(new ObjectSet<FOO>());
TimChang
  • 2,249
  • 13
  • 25