为了账号安全,请及时绑定邮箱和手机立即绑定

C#如何动态检测泛型类型

C#如何动态检测泛型类型

C#
互换的青春 2022-07-10 10:32:01
我有一种方法,我喜欢使用反射机制执行一些不同的强制转换。private static T GetObject<T>(Dictionary<string, object> dict){    Type type = typeof(T);    var obj = Activator.CreateInstance(type);    foreach (var kv in dict)    {        var p = type.GetProperty(kv.Key);        Type t = p.PropertyType;        Type t2 = kv.Value.GetType();        if (t == t2)        {            p.SetValue(obj, kv.Value);        }        else if (!IsPrimitive(p.PropertyType))         {            p.SetValue(obj, GetObject<class of p>((Dictionary<string, object>) kv.Value)); //???        }        else        {            p.SetValue(obj, (primitive)(kv.Value)); //???                            }    }    return (T)obj;}已编辑我有一本字典,我想将其转换为自定义类,字典中的每个键都是一个属性,每个字典值都是该属性的值。问题出现在两种情况下,当类属性类型和字典值类型都是原始类型但它们具有不同的类型时(例如,属性是 int 但字典值是 long),当属性值是另一个自定义类并且在这种情况下,字典值总是另一个字典如何动态检测必要的演员表/演员表?
查看完整描述

2 回答

?
Smart猫小萌

TA贡献1911条经验 获得超7个赞

首先查看类型是否与分配兼容


if (t.IsAssignableFrom(t2))

否则转换为


object converted = Convert.ChangeType(kv.Value, t);

这应该处理很多情况。


由于您必须使用仅在运行时知道的类型递归调用该方法,因此最好使用GetObject. 原来的方法只调用非泛型的


private static T GetObject<T>(Dictionary<string, object> dict)

    where T : class, new() // Suggested by Brett Caswell.

{

    return (T)GetObject(dict, typeof(T));

}

请注意,泛型类型参数始终在编译时解析。由于您必须在运行时动态解析类型,因此它们在这里更具障碍。您可以使用反射构造一个通用方法调用,但我认为这样做没有任何优势。它很复杂,而且类型不安全。类型安全只能由编译器强制执行。


private static object GetObject(Dictionary<string, object> dict, Type objectType)

{

    object obj = Activator.CreateInstance(objectType);

    foreach (var kv in dict) {

        PropertyInfo prop = objectType.GetProperty(kv.Key);

        Type propType = prop.PropertyType;

        object value = kv.Value;

        if (value == null) {

            if (propType.IsValueType) { // Get default value of type.

                value = Activator.CreateInstance(propType);

            }

        } else if (value is Dictionary<string, object> nestedDict) {

            value = GetObject(nestedDict, propType);

        } else if (!propType.IsAssignableFrom(value.GetType())) {

            value = Convert.ChangeType(value, propType);

        }

        prop.SetValue(obj, value);

    }

    return obj;

}


查看完整回答
反对 回复 2022-07-10
?
森栏

TA贡献1810条经验 获得超5个赞

解决这个问题的更好方法是应用Bob 叔叔的SOLID 原则之一,即开闭原则。这是此原则的经典示例


public abstract class Shape

{

        public abstract double Area();

 } 


public class Rectangle : Shape

{

    public double Width { get; set; }

    public double Height { get; set; }

    public override double Area()

    {

        return Width*Height;

    }

}


public class Circle : Shape

{

    public double Radius { get; set; }

    public override double Area()

    {

        return Radius*Radius*Math.PI;

    }

通过这种方式,您不必创建 if else 树,但通过实现抽象类,您必须在每次将其与任何类一起使用时实现 Area 方法。希望服务于目的


查看完整回答
反对 回复 2022-07-10
  • 2 回答
  • 0 关注
  • 180 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信