【问题标题】:Change data type dynamically in c#在 C# 中动态更改数据类型
【发布时间】:2013-07-16 12:05:43
【问题描述】:

我想动态转换数据类型。

我的代码:

private static void updateValues(SqlDataReader reader)  
{
        USR_AddressItem item = new USR_AddressItem();
        Type ConvertNewType;
        ConvertNewType = Type.GetType(item.UserId.GetType().Name);
        item.UserId = (ConvertNewType)(reader[UserDAL.USR_Address.FieldNames.UserId]);

}

这里的数据类型只是动态的。因为我想在运行时为这个变量赋值。我将从SqlDataReader 获取值。此阅读器始终返回字符串值。我将在全局范围内使用此方法。

【问题讨论】:

  • 这个问题的“动态”是什么?
  • 动态类型转换很困难,你经常想用一个switch case来实现你已经实现的类型转换,却发现你无法切换Type类型的变量
  • 检查我的答案并享受。使用泛型小菜一碟!
  • Type.GetType(item.UserId.GetType().Name); 喜欢这个:) 为什么不item.UserId.GetType()
  • 类似这样的东西:gist.github.com/Alxandr/6008481?

标签: c# asp.net


【解决方案1】:

嗯,你需要的是类型推断

你不需要提前知道数据类型,你让运行时解决它,像这样:

private static void updateValues(SqlDataReader reader)  
{
    USR_AddressItem item = new USR_AddressItem();
    item.UserId = GetConverter(item.UserId)(reader[UserDAL.USR_Address.FieldNames.UserId]);
}

我的魔法就在这里:

static Func<string, T>  GetConverter<T>(T example)      
{
    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);
    }

【讨论】:

    【解决方案2】:

    在您展示的示例中,只需说:

    Userid = new System.Guid(value);
    

    因为Guid 的构造函数需要一个字符串来创建对象。

    也就是说,除非您尝试做其他事情,在这种情况下,请澄清您的问题!

    【讨论】:

    • -1; OP 问题是关于在不使用本机代码的情况下将字符串转换为 GUID,我认为这只是一个通用示例,因为问题的标题是“在 c# 中动态更改数据类型”而不是“如何将字符串转换为 GUID”。
    • 鉴于帖子的语法很差(我最初对其进行了编辑以使其更好),以及给出的示例代码,我不清楚 OP 是否打算让它成为“动态”的方式我们通常会考虑动态。如果那是 OP 真正想要的,他们需要把它说得更清楚。
    • 对不起。我只在运行时知道该数据类型。这是我的原始代码` USR_AddressItem item = new USR_AddressItem();类型转换新类型; ConvertNewType = Type.GetType(item.UserId.GetType().Name); item.UserId = (ConvertNewType)(reader[UserDAL.USR_Address.FieldNames.UserId]);`
    • @user2354274 把它放在你的问题中,使用编辑功能。如果您觉得语法或格式有困难(您会学到),不要太担心语法或格式,社区应该能够解决它。
    【解决方案3】:

    在Guid 的情况下,情况会大不相同,因为没有真正的转换。 请看,使用string 构建Guid 必须像这样:

    var guid = new Guid("DAABED91-39AC-4805-9015-1B03E4B5706A");
    

    您当然可以为此使用Reflection,但要确定为没有真正转换的类型使用什么构造函数,这将是一个非常复杂的算法。

    但是,对于许多其他类型,您可以考虑这样的事情:

    // would generate something like ToInt32...
    var methodName = string.Format("To{0}", t.Name.Split('.').Last());
    
    var methodInfo = Convert.GetType().GetMethod(methodName);
    if (methodInfo == null) { return default(t); }
    
    var val = methodInfo.Invoke(null, new object[] { valToConvert });
    

    注意:此代码未经测试。这是一个指南,我认为它非常接近,但您可能需要稍微按摩一下。

    【讨论】:

    • 对不起。我只在运行时知道该数据类型。这是我的原始代码:USR_AddressItem item = new USR_AddressItem(); Type ConvertNewType; ConvertNewType = Type.GetType(item.UserId.GetType().Name); item.UserId = (ConvertNewType)(reader[UserDAL.USR_Address.FieldNames.UserId]);
    • @user2354274,所以将t替换为ConvertNewType。
    • 如何为 item.UserId 赋值。它显示转换错误
    • @user2354274,您需要使您的方法通用(例如ConvertType&lt;T&gt;),以便您可以从调用中转换值(例如(T)methodInfo.Invoke...)。因此,根据您当前的代码,您将在确定要转换为的类型后调用此 new 方法,而 new 方法 将拥有其余代码.
    猜你喜欢
    • 2012-01-20
    • 2022-01-02
    • 2019-10-30
    • 2021-06-16
    • 1970-01-01
    • 2014-04-14
    • 2016-08-25
    • 1970-01-01
    • 2020-03-05
    相关资源
    最近更新 更多