Is possible to cast a variable to a type stored in another variable?

前端 未结 5 926
别跟我提以往
别跟我提以往 2021-01-03 23:18

This is what I need to do:

object foo = GetFoo();
Type t = typeof(BarType);
(foo as t).FunctionThatExistsInBarType();

Can something like th

相关标签:
5条回答
  • 2021-01-04 00:01

    Since dynamics were added to c#, I think we can do it in this way:

    class Program {
        static void Main(string[] args) {
            List<int> c = new List<int>(); 
            double i = 10.0;
            Type intType = typeof(int);
            c.Add(CastHelper.Cast(i, intType)); // works, no exception!
        }
    }
    
    class CastHelper {
        public static dynamic Cast(object src, Type t) {
            var castMethod = typeof(CastHelper).GetMethod("CastGeneric").MakeGenericMethod(t);
            return castMethod.Invoke(null, new[] { src });
        }
        public static T CastGeneric<T>(object src) {
            return (T)Convert.ChangeType(src, typeof(T));
        }
    }
    
    0 讨论(0)
  • 2021-01-04 00:08

    You can use the Convert.ChangeType method.

    object foo = GetFoo(); 
    Type t = typeof(string);
    string bar = (string)Convert.ChangeType(foo, t);
    
    0 讨论(0)
  • 2021-01-04 00:13

    No, you cannot. C# does not implement duck typing.

    You must implement an interface and cast to it.

    (However there are attempts to do it. Look at Duck Typing Project for an example.)

    0 讨论(0)
  • 2021-01-04 00:16

    Provided you know all required types at compile-time, duck typingis (sort of) possible:

    class BarFoo {}
    class Foo {}
    class Bar {}
    
    class Program
    {
        static void Main( )
        {
            var foo = new Foo( );
            var bar = new Bar( );
            var barfoo = new BarFoo( );
    
            Console.WriteLine(DoStuff(foo));
            Console.WriteLine(DoStuff(bar));
            Console.WriteLine(DoStuff(barfoo));
    
        }
    
        static string DoStuff(Foo foo) { return "DoStuff(Foo foo)"; }
        static string DoStuff(Bar bar) { return "DoStuff(Bar bar)"; }
        static string DoStuff(Base fb) { return "DoStuff(object fb)"; }
    }
    

    Output:

    Dostuff(Foo foo)
    Dostuff(Bar bar);
    DoStuff(object fb);
    

    If you end up implementing a lot of methods that basically do exactly the same, consider implementing an interface.

    0 讨论(0)
  • 2021-01-04 00:19

    Your original question was flawed in that you ask to treat a variable as a type which is not known at compile time but note that you have string defined on the left hand side when you declare your variable. C# as of 3.5 is statically typed.

    Once dynamic is available you could do something like this:

    dynamic foo = GetFoo();
    foo.FunctionThatExistsInBarType(); 
    

    For when you don't know what the type is but you know it will always support the instance method FunctionThatExistsInBarType();

    for now you are forced to use reflection (or code gen which really amounts to much the same thing but more expensive up front and faster later).

    // any of these can be determined at runtime
    Type t = typeof(Bar);
    string methodToCall = "FunctionThatExistsInBarType";
    Type[] argumentTypes = new Type[0];
    object[] arguments = new object[0];
    object foo;
    // invoke the method - 
    // example ignores overloading and exception handling for brevity
    // assumption: return type is void or you don't care about it
    t.GetMethod(methodToCall, BindingFalgs.Public | BindingFlags.Instance)
        .Invoke(foo, arguments);
    
    0 讨论(0)
提交回复
热议问题