如何在c#

时间:2018-03-28 10:43:20

标签: c# reflection type-inference

我试图动态更改对象的数据类型, 这是我的情景 我在数据表中有数据,我需要将它映射到c#

中的对象

以下是我遵循的步骤

  1. 循环访问数据表并获取每个数据行
  2. 在该循环中获取列
  3. 传递列名,新对象为属性赋值,数据表单元格值为新方法。
  4. 这是示例代码

                m1()
                {
                    foreach (DataRow row in inputTable.Rows)
                    {
                        foreach (DataColumn col in inputTable.Columns)
                        {
                            m2(col.caption,row[col.caption].toString(),new product())
                        }
                    }
                }
    
                m1(string columnName,string cellValue,product mappingEntity){
                    foreach (var prop in entityToMap.GetType().GetProperties())
                        {
                            if (prop.Name.ToLower() == column.ToLower())
                            {
                                prop.SetValue(entityToMap, GetConverter(t)(cellValue));
                                break;
                            }
                            else if (prop.Name == "Site")
                            {
                                entityToMap.Site = MapSite(column, cellValue, new Domain.Entities.Site());
                                break;
                            }
                            else if (prop.Name == "Product_categories")
                            {
                                entityToMap.Product_categories.Add(MapProductToCategory(column, cellValue, new Domain.Entities.ProductToCategory()));
                            }
                            else if (prop.Name == "Category_searchgroups")
                            {
                                entityToMap.Category_searchgroups.Add(MapCategoryToSearchGroup(column, cellValue, new Domain.Entities.CategoryToSearchGroup()));
                            }
                }
    

    现在我需要动态更改赋值的数据类型。

     if (prop.Name.ToLower() == column.ToLower())
        {
          Type t = prop.PropertyType;
          prop.SetValue(entityToMap, GetConverter(t)(cellValue));
          break;
        }
    

    所以我在这里找到了类型推断问题 Change data type dynamically in c#

     static Func<string, T> GetConverter<T>(T value)
            {
                return (x) => Convert<T>(x);
            }
        static T Convert<T>(string val)
        {
            Type destiny =typeof(T);
    
            // See if we can cast           
            try
            {
                return (T)(object)val;
            }
            catch { }
    
            // See if we can parse
            try
            {
                return (T)destiny.InvokeMember("Parse", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public, null, null, new object[] { val });
            }
            catch { }
    
            // See if we can convert
            try
            {
                Type convertType = typeof(Convert);
                return (T)convertType.InvokeMember("To" + destiny.Name, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public, null, null, new object[] { val });
            }
            catch { }
    
            // Give up
            return default(T);
        }
    

    问题是我有反射对象,我无法传递反射对象,因为它在该上下文中无效, 任何人都可以帮我解决这个问题吗? 感谢

1 个答案:

答案 0 :(得分:1)

我不确定这是否是你需要的,但听起来像是。

public static T RowToObjectClass<T>(DataRow r) where T : new()
{
    T obj = new T();
    foreach (PropertyInfo pi in typeof(T).GetProperties().Where(p => p.CanWrite))
    {
        pi.SetValue(obj, Convert.ChangeType(r[pi.Name], pi.PropertyType));
    }
    return obj;
}

static void Main(string[] args)
{
    DataTable dt = new DataTable();
    dt.Columns.Add(new DataColumn("id", typeof(string)));
    dt.Columns.Add(new DataColumn("date", typeof(string)));

    dt.Rows.Add(new object[] { 1.ToString(), new DateTime(2018, 1, 1).ToString() });
    dt.Rows.Add(new object[] { 2.ToString(), new DateTime(2018, 2, 2).ToString() });

    foreach (DataRow r in dt.Rows)
    {
        Console.WriteLine("Row:   " + r[0].ToString() + " (" + r[0].GetType() + ")" + ", " + r[1].ToString() + " (" + r[1].GetType() + ")");
        MyClass c = RowToObjectClass<MyClass>(r);
        Console.WriteLine("Class: " + c.Id.ToString() + " (" + c.Id.GetType() + ")" + ", " + c.Date.ToString() + " (" + c.Date.GetType() + ")");
    }
}

public class MyClass
{
    public int Id { get; set; }
    public DateTime Date { get; set; }
}