简体   繁体   中英

Dynamic cast in c# in runtime

I have 2 classes as you can see:

  static void Main(string[] args)
    {

        object m = (??????)"salam";
    }


public class A
{
    public string name { set; get; }
    public static implicit operator A(string _name)
    {
        A aa = new A();
        aa.name = _name;
        return aa;
    }
}
public class B
{
    public string family { set; get; }
    public static implicit operator B(string _family)
    {
        B bb = new B();
        bb.family = _family;
        return bb;
    }
}

I need to cast my string in runtime in this line:

object m = (??????)"salam";

Is there any solution to pass my class name as a string to cast my value.for example in runtime I need to cast "salam" to A or maybe B

The static cast is working good like this

 object m = (A)salam";
 object m = (B)"salam";

But I need to cast my string in runtime

Type x=null;
If(condition) 
x can be type of A
else 
x can be type of B

object m = (x)"salam";

You need to use Interfaces for such a need. The following code shows how to do so.

To simulate your situtation, I wrote a method to return either A or B based on time. Here the list contains a bunch of objects which may be of Type A or B , depending on the second of execution. In the real-world scenario, you would get your types in various other ways.

public class StackOverflowQuestion
{
    public static void Run()
    {
        List<IBase> list = new List<IBase>();
        string types = "";
        for (int i = 0; i < 10; i++)
        {
            var randomType = GiveMeARandomIBaseType();
            System.Threading.Thread.Sleep(750);
            IBase hello = randomType.Convert("salam");
            list.Add(hello);
            types += hello.GetType().Name + ",";
        }

        types = types.Trim(',');
        //sample result : B,B,A,B,A,A,B,A,B,B
    }

    static IBase GiveMeARandomIBaseType() {
        if (DateTime.Now.Second % 2 == 0)
            return new A();
        else
            return new B();
    }
}

public interface IBase {
    public IBase Convert(string s);
}
public static class MyExtensions {
    public static T Convert<T>(this string str, IBase b) where T : IBase {
        try
        {
            return (T)b.Convert(str);
        }
        catch (Exception)
        {
            return default;
        } 
    }
}
public class A : IBase
{
    public IBase Convert(string s) {
        return (A)s;
    }
    public string name { set; get; }

    public static implicit operator A(string _name)
    {
        A aa = new A();
        aa.name = _name;
        return aa;
    }
}
public class B : IBase
{

    public IBase Convert(string s)
    {
        return (B)s;
    }
    public string family { set; get; }
    public static implicit operator B(string _family)
    {
        B bb = new B();
        bb.family = _family;
        return bb;
    }
}

I had a similar problem and after all the study and time, I was able to approach the desired result in the following way. I used an internal method to access (the inside of) the class and this method returns the cast desired result.

Step 1: in class

public class A
    {
       public string Name { set; get; }

        public static implicit operator A(string name)
        {
            return new A
            {
                Name = name
            };
        }

        public A GetCasting(object a)
        {
            A i = (A)a;
            return i;
        }
    }

    public class B
    {
        public string Family { set; get; }

        public static implicit operator B(string family)
        {
            return new B
            {
                Family = family
            };
        }
        public B GetCasting(object b)
        {
            B i = (B)b;
            return i;
        }
    }

Step 2: in controller or code

    var className = "A";
    var classMethod = "GetCasting";
    var classType = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsClass && t.Name == className).FirstOrDefault();
    var classInstance = Activator.CreateInstance(classType);
    var castMethod = classType.GetMethod(classMethod);
    var yourObject = "salam";
    var objectData = new object[] { yourObject };
    var resultObject = castMethod.Invoke(classInstance, objectData);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM