【问题标题】:Dynamic cast in c# in runtime在运行时在 C# 中动态转换
【发布时间】:2020-11-17 11:56:34
【问题描述】:

如您所见,我有 2 个课程:

  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;
    }
}

我需要在运行时在这一行中转换我的字符串:

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

是否有任何解决方案可以将我的类名作为字符串传递来转换我的值。例如,在运行时我需要将“salam”转换为AB

静态演员像这样工作得很好

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

但我需要在运行时转换我的字符串

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

object m = (x)"salam";

【问题讨论】:

标签: c# reflection casting implicit-conversion


【解决方案1】:

您需要使用接口来满足这种需求。以下代码显示了如何执行此操作。

为了模拟您的情况,我编写了一个基于时间返回AB 的方法。 这里list 包含一堆对象,这些对象的类型可能是AB,具体取决于执行的秒数。在现实世界的场景中,您可以通过其他各种方式获取您的类型。

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;
    }
}

【讨论】:

  • 谢谢 Mahdi。我知道,但我需要在运行时进行转换。我的意思是在某些情况下,我的转换类可以是 A,有时也可以是 B,具体取决于我的应用程序中的某些情况。
  • @EhsanAkbar 我已经更新了我的答案。请检查一下。
  • 天啊!!!这个答案确实救了我的命。太感谢了。它应该是公认的答案。 @MahdiTahsildari
【解决方案2】:

我遇到了类似的问题,经过所有的研究和时间,我能够通过以下方式接近预期的结果。 我使用了一个内部方法来访问类(内部),这个方法返回了转换所需的结果。

第一步:上课

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;
        }
    }

第 2 步:在控制器或代码中

    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);

【讨论】:

  • 嗨,阿米尔侯赛因。尽管它有效,但使用反射并不是一个好的选择,因为人们可能会忘记为类添加正确的方法。这种方法很容易出现异常,因为编译器会尝试调用该方法,无论它是否存在。使用接口可以防止您在运行时遇到异常。相反,如果你的类缺少正确的方法,你会在编译前被警告。
猜你喜欢
  • 1970-01-01
  • 2012-05-12
  • 2017-08-21
  • 1970-01-01
  • 2012-09-06
  • 1970-01-01
  • 1970-01-01
  • 2011-02-21
  • 1970-01-01
相关资源
最近更新 更多