[C#.NET] 類型轉換前要不要先判斷?直接強制轉型好嗎?
先歸納一下在C#裡提供了哪些型別的轉換,轉型和型別轉換 (C# 程式設計手冊)
boxing/unboxing:
Boxing 是一種隱含轉換,可將實值型別轉換成 object 型別,Unboxing 是明確轉型將object轉換成其它型別,我們應該極力的避免這樣的狀況發生。
int a = 5;
object b = (object)a;//boxing
object c = 5;
int d = (int)c;//unboxing
字串型別轉換成實值型別:
int f = int.Parse("3");
明確轉型:
long e = System.Convert.ToInt64(257);
bool g = System.Convert.ToBoolean("true");
byte h = (byte)e; //long轉byte可能會造成資料丟失
參考型別的轉換:
比如我有兩個類別叫Company 及Family
public class Company
{
public string Name { get; set; }
public string Address { get; set; }
}
public class Family
{
public string Name { get; set; }
public string Address { get; set; }
}
我想要用 as 將 company 轉成 Family,沒意外的話 family 會得到null
object company = new Company();
Family family = company as Family;
如果使用明確轉型,沒意外應該會拋出InvalidCastException的例外。
object company = new Company();
Family family = (Family)company;
記得以前剛接觸C#時,需要一個功能叫"驗証字串是否為數字",下列的寫法也很常見(相當的不建議這樣寫),別忘了!使用try/catch會降低程式碼的效能,我們應該找尋其他的辦法。
public bool IsNumeric(string data)
{
try
{
long h = System.Convert.ToInt64("20");
return true;
}
catch (Exception)
{
return false;
}
}
使用明確轉型又有可能會丟包或出錯(InvalidCastException),我們能有其他辦法嗎?有的,我們可以先判斷資料型別然後再轉型。
實值型別的轉換判斷,使用TryParse方法,轉換結果會丟到result,並回傳bool是否為數字
public bool IsNumeric(string data)
{
int result;
if (int.TryParse(data, out result))
return true;
else
return false;
}
當然也可以寫成這樣,不必擔心數據是否丟包,轉換失敗會回傳null,轉換成功會得到正確的byte資料。
public static byte? IsNumeric(string data)
{
byte result;
if (byte.TryParse(data, out result))
return (byte)result;
else
return null;
}
用is關鍵字,無法轉換會回傳null,轉換成功會得到正確的int資料。
public int? IsNumeric(object o)
{
int i;
if (o is byte)
{
i = (int)o;
return i;
}
else
{
return null;
}
}
參考型別的轉換判斷,使用is關鍵字判斷型別再用as轉型,下列程式碼是我常用在搜尋控制項的片斷。
foreach (Control ctrl in this.Controls)
{
if (ctrl is TextBox)
{
TextBox textbox = ctrl as TextBox;
Console.WriteLine(textbox.Text);
}
else if (ctrl is Button)
{
Button button = ctrl as Button;
Console.WriteLine(button.Text);
}
}
或是寫成這樣
foreach (Control ctrl in this.Controls)
{
if (ctrl is TextBox)
{
TextBox textbox = (TextBox)ctrl;
Console.WriteLine(textbox.Text);
}
else if (ctrl is Button)
{
Button button = (Button)ctrl;
Console.WriteLine(button.Text);
}
}
我會比較建議使用as來轉型,用as轉型時若轉型失敗會得到null不會發生例外,以下面的片斷程式碼來看,甚至不需要用到is,直接判斷as轉型是否為null
object company = new Company();
Family family = company as Family;
if (family != null)
{
//TODO
}
else
{
//TODO
}
若是用明確轉型,我們可能還要檢查是否為null以及捕捉例外,這樣一來便會降低程式碼的效能
object company = new Company();
Family family = null;
try
{
family = (Family)company;
}
catch (InvalidCastException ex)
{
//throw ex;
}
後記:
1.應該優先選擇使用as來轉型,當無法使用as轉型時,可以先使用is判斷,再進行明確轉型。
2.當可以使用as轉型時,判斷轉型結果是否為null,便可省略is判斷。
3.必要時is加上as可以讓程式碼更靈活。
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET