2016-02-26 26 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]; 
    } 
} 

編輯: - 即採用現場方法可能更好,因爲它是速度更快,答案這並不意味着這是最好的方式來充分利用這一點,如下代碼將被改變更明確。

如果您打算將此格式應用於各種浮點(或甚至整數)類型,並且在編寫代碼時不知道它們的類型,我的方法會更合適。