2016-02-26 114 views
2

我有几个DataRow一个DataTable,我想在新DataTable格式化,但是我发现一个问题,当我尝试格式化一些行:ItemArray以字符串格式无效

DataTable ret = functionThatGetsaDataTableUsingSQL(); //Original DataTable 
DataTable dt = new DataTable(); //Final DataTable 
foreach (DataRow dr in ret.Rows) 
{ 
    DataRow row = dt.Rows.Add(); 
    for (int j = 0; j < dr.ItemArray.Length; j++) 
    { 
     if (j == 14) row[j] = dr.ItemArray[j].ToString("C2"); 
     else row[j] = dr.ItemArray[j]; 
    } 
} 

row[j] = dr.ItemArray[j].ToString("C2");不起作用No overload for method 'ToString' takes 1 arguments

我试图尽可能地简化代码,以便只专注于格式化部分。

如何格式化此值?我知道在使用ToString("C2")之前我可以投出Convert.ToDecimal(),但这是唯一的方法吗?

+0

[方法“ToString”有1个参数没有重载的可能的重复](http://stackoverflow.com/questions/9091177/no-overload-for-method-tostring-takes-1-arguments) – Alex

回答

2

ItemArrayobject[]Object.ToString没有参数。我想这实际上是一种货币价值。然后使用DataRow.Field扩展方法将其强制转换:

foreach (DataRow dr in ret.Rows) 
{ 
    DataRow row = dt.Rows.Add(); 
    for (int j = 0; j < dr.ItemArray.Length; j++) 
    { 
     if (j == 14) 
      row[j] = dr.Field<decimal>(j).ToString("C2"); // use the correct type 
     else 
      row[j] = dr.ItemArray[j]; 
    } 
} 

这里有一个优化的版本,ItemArray-property有额外的开销,因为吸气总是创建一个新的数组(因为你可以看到here):

foreach (DataRow dr in ret.Rows) 
{ 
    DataRow row = dt.Rows.Add(); 
    foreach(DataColumn col in ret.Columns) 
    { 
     if (col.Ordinal == 14) 
      row.SetField(col.Ordinal, dr.Field<decimal>(col).ToString("C2")); // use the correct type 
     else 
      row.SetField(col.Ordinal, dr[col]); 
    } 
} 
+0

该字段是我想要转换为货币的十进制值。无论哪种方式解决了我的问题。只是想知道:使用ItemArray [i]'和Field (i)'得到一个值是否有区别?只是要求,因为它是一个循环,将循环至少一千次迭代。 –

+1

@MiquelColl:使用'DataRow'索引器或'Field'方法。 ['ItemArray'-property](https://msdn.microsoft.com/en-us/library/system.data.datarow.itemarray(v = vs.110).aspx)有额外的开销,因为getter总是创建一个新的阵列。 http://referencesource.microsoft.com/#System.Data/System/Data/DataRow。cs,c49b336f59c8f808,引用 –

+1

@MiquelColl:我已经编辑了我的答案,以显示没有ItemArray的方法。您可以使用'row [index] ='来代替'SetField'。如果你有可为空的类型,前者更好。 –

1

C2意味着它可以转换成小数点后两位的货币,但是如果直接放置字符串,它会转换为“jkld”,因此必须让编译器知道您的源数据类型,并且一旦确定它是类型的双然后它会接受这样的

正确方法

double myPrice; 
myPrice.ToString("C2"); 

这是理论上的答案,但你应该知道,将来你就不会感到困惑,快乐编码:)

+0

嗯,我实际上在我的问题中说我知道一个小数/双将可以格式化,但我想知道是否有一种方法可以省略演员阵容或转换。谢谢你。 –

+0

好的@MiquelColl –

1

您可以在任何使用的String.format。

string.Format("{0:C2}", o); 

将编译任何类型和值的o。

DataTable ret = functionThatGetsaDataTableUsingSQL(); //Original DataTable 
DataTable dt = new DataTable(); //Final DataTable 
foreach (DataRow dr in ret.Rows) 
{ 
    DataRow row = dt.Rows.Add(); 
    for (int j = 0; j < dr.ItemArray.Length; j++) 
    { 
     if (j == 14) row[j] = string.Format("{0:C2}", dr.ItemArray[j]); 
     else row[j] = dr.ItemArray[j]; 
    } 
} 

编辑: - 即采用现场方法可能更好,因为它是速度更快,答案这并不意味着这是最好的方式来充分利用这一点,如下代码将被改变更明确。

如果您打算将此格式应用于各种浮点(或甚至整数)类型,并且在编写代码时不知道它们的类型,我的方法会更合适。