【问题标题】:C# Best way to convert dynamic to stringC#将动态转换为字符串的最佳方法
【发布时间】:2021-07-28 16:47:56
【问题描述】:

以下内容从 DataTable 中获取一个字段并将其转换为字符串。有没有更简洁的方法将动态转换为字符串?

dynamic value = dataTable.Rows[i].Field<dynamic>(columnName);
value = (value == null) ? null : value.ToString();

【问题讨论】:

    标签: c#


    【解决方案1】:
    string value = Convert.ToString(dataTable.Rows[i][columnName]);
    

    标准格式将启动,无需诸如泛型、扩展方法或动态之类的东西。

    【讨论】:

    • 不是更简单吗?不需要转换吧?这不好吗?字符串值 = dataTable.Rows[i][columnName];
    • @cloud 仅在它已经 字符串时才有效。 Convert 不在乎它是什么。
    • 那么,为了安全起见,在处理动态时,我们应该始终使用 convert,还是“取决于”类型的情况?
    • @cloudsteifebro 恰恰相反,我会说通常不需要使用动态,它会伤害你很多
    【解决方案2】:

    首先,正如 Marc 在他的回答中提到的“标准格式将生效,不需要泛型、扩展方法或动态之类的东西”,所以在你的情况你不必使用dynamic关键字,你可以直接转换为字符串,但谈到从动态转换为字符串我有两种方法:

    第一种方式

    string x = Convert.ToString(value) // value is a dynamic object
    

    优点:如果您不确定编译后的数据类型是否支持转换为字符串或硬编码,这是一种很好的转换方式 以 int 为例,

    缺点:如果您尝试在 Convert.ToString(value) // value is a dynamic object 内创建 Extension Method ,则这种方式可能会导致错误,当我这样做时 给我这个错误:“扩展方法不能动态 派出。考虑强制转换动态参数或调用 没有扩展方法语法的扩展方法”.

    所以如果你使用 Asp.Net Core HttpContext.Session.SetString() 并且您将 Convert.ToString(value) // value is dynamic object 作为内联转换放入争论中,它会在 cons 部分中为您提供错误,要解决此问题,您可以将函数参数之外的变量分配给 Covert.ToString(value) 结果然后将变量发送到扩展函数参数:

    dynamic value = 10;
    HttpContext.Session.SetString("key",Convert.ToString(value));  <-- error
    

    解决:

    dynamic value = 10;
    string x = Convert.ToString(value);
    HttpContext.Session.SetString("key",x);  // works fine
    

    或者使用第二种方式(强制转换),确保编译后的数据类型支持强制转换为字符串

    HttpContext.Session.SetString("key",(string)value);
    

    第二种方式
    cast dynamicstring 如果编译后的数据类型支持

    string x = (string)value;  //value is dynamic object
    

    优点: - 如果您想在 Extension method争论 - 如果您想确保编译的数据类型支持转换为 string 并基于此生成异常

    ,这也很有用

    缺点:这不适用于所有数据类型,因此如果您想要更通用的转换方法,建议使用第一种方法


    MS docs 中所述,“动态类型允许其发生的操作绕过编译时类型检查。相反,这些操作在运行时解决。"

    所以dynamic 变量的数据类型是在运行时编译的,它采用dynamic 以外的类型,如果解释的对象支持它,您可以使用casting,或者使用Convert.ToString() 进行更通用的类型转换。

    PS:如果您要转换为字符串以外的数据类型,则可能会面临数据丢失,例如将 float 转换为 int ,因此请注意这一点。

    【讨论】:

    • 虽然这可能会提供问题的答案,但需要一些解释。请更新问题,解释此解决方案的工作原理和原因。
    • 无法保证字段 is 的值是字符串,因此 OP 要求如何将其 convert 转换为字符串。您的代码仅在对象实际上是字符串时才有效,而只要Convert.ToString 可以处理它,则接受的答案将有效,这更有可能。请注意,例如,如果基础值为int,您将收到RuntimeBinderException 的运行时错误:“无法将类型'int' 转换为'字符串'”。
    • @LasseVågsætherKarlsen 实际上 casting 是一种转换方式,可以处理一些在 C# 中未作为字符串处理的数据类型,例如 NewtonsoftJObject,您可以转换 numeric data inside json string to string with casting,谁说要保证字段的值是字符串,如果不是的话可能要抛出异常't。
    • 昨天更新 VisualStudio 后,我能够做到这一点:var listOfInts = new List&lt;int&gt;();var x = listOfInts.Select(i =&gt; Convert.ToString(i));
    • 我发现这个解释很有用。由于我使用 Xamarin 开发应用程序,因此当链接器行为设置为仅 SDK 时,总是会出现此重载字符串错误。也许 xamarin 无法从动态中读取字符串,因此将 (string)dy_obj.var 放入使其工作而不是 Convert.ToString(dy_obj.var)
    【解决方案3】:

    我有一种情况,动态应该是一个字符串,但在错误情况下是一个数字(我调用并且无法更改的代码就是这样做的)。

    就我而言:

    string x = value as string;
    if (x == null)
    {
       // error condition
    } else {
       //use x here
    }
    

    【讨论】:

    • 我最好使用is 关键字,例如if (x is null) { ... }
    猜你喜欢
    • 2014-06-21
    • 2010-10-10
    • 1970-01-01
    • 2011-12-27
    • 2017-07-26
    • 1970-01-01
    • 2010-10-21
    • 2014-01-28
    相关资源
    最近更新 更多