[C#] Convert(轉型)、Parse(強制轉型)、TryParse(安全轉型)與運算子轉型的差別、效能

最近再磨練基本功的時候複習了常用到的「轉型」,找一找資料後統整了一下才比較搞懂這些差異。

轉型別基本上分為下列五種:

  1. Convert(轉型)
1
2

Convert.ToInt32("5.5");
  1. Parse(強制轉型)
1
2
3

(int)(5.5);
int.Parse("5.5");
  1. TryParse(安全轉型)
1
2
3

int i = 0;
int.TryParse("5.5", out i)
  1. 運算子 - as
1
2

CustomModel model = obj as CustomModel
  1. 運算子 - is
1
2

CustomModel model = obj is CustomModel

根據參考資料差異如下:

  1. Convert 是將值轉換成最接近的 32 位元帶正負號的整數
1
2
3
4
5

Console.WriteLine(Convert.ToInt32("4.5")); //result = 4
Console.WriteLine(Convert.ToInt32("4.51"));//result = 5
Console.WriteLine(Convert.ToInt32("5.4")); //result = 5
Console.WriteLine(Convert.ToInt32("5.5")); //result = 6
  1. Parse 則是無條件捨去( long、float、double、或 decimal )
1
2
3
4
5

Console.WriteLine((int)(4.5)); //result = 4
Console.WriteLine((int)(4.51));//result = 4
Console.WriteLine((int)(5.4)); //result = 5
Console.WriteLine((int)(5.5)); //result = 5
  1. TryParse 會回傳一布林值來判斷是否轉換成功
1
2
3
4
5
6
7
8
9
10
11

string s1 = "1234";
string s2 = "1234.65";
string s3 = null;
string s4 = "123456789123456789123456789123456789123456789";
bool success = false;
int result = 0;
success = Int32.TryParse(s1, out result); //-- success => true; result => 1234
success = Int32.TryParse(s2, out result); //-- success => false; result => 0
success = Int32.TryParse(s3, out result); //-- success => false; result => 0
success = Int32.TryParse(s4, out result); //-- success => false; result => 0
  1. as 若轉型失敗會回傳null,且只能用於參考類型,不能應用於值類型(除非是Nullable的值類型)。
1
2
3
4
5
6
7
8
9
10

CustomModel model = obj as CustomModel;
if(model != null)
{
//轉型成功
}
else
{
//轉型失敗
}
  1. is 若轉型失敗則會跳Exception
1
2
3
4
5
6
7
8
9

try
{
CustomModelt = obj is CustomModel;
}
catch
{
//轉型失敗
}

2017/09/24 更新

(Net Core 2.0)效能上 Parse > TryParse > Convert。

測試程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();

sw.Start();
for (int i = 0; i < 10000000; i++)
{
Convert.ToInt32(i.ToString());
}
sw.Stop();

Console.WriteLine(string.Format("Convert.ToInt32 = {0} ms", sw.ElapsedMilliseconds));
sw.Reset();

sw.Start();
for (int i = 0; i < 10000000; i++)
{
int.Parse(i.ToString());
}
sw.Stop();

Console.WriteLine(string.Format("int.Parse = {0} ms", sw.ElapsedMilliseconds));
sw.Reset();

sw.Start();
for (int i = 0; i < 10000000; i++)
{
int.TryParse(i.ToString(), out int tmp);
}
sw.Stop();

Console.WriteLine(string.Format("int.TryParse = {0} ms", sw.ElapsedMilliseconds));
sw.Reset();

object model = new TestModel
{
Tmp = 100
};

sw.Start();
for (int i = 0; i < 10000000; i++)
{
var tmp = model as TestModel;
}
sw.Stop();

Console.WriteLine(string.Format("as = {0} ms", sw.ElapsedMilliseconds));
sw.Reset();

sw.Start();
for (int i = 0; i < 10000000; i++)
{
var tmp = model is TestModel;
}
sw.Stop();

Console.WriteLine(string.Format("is = {0} ms", sw.ElapsedMilliseconds));
sw.Reset();

Console.ReadKey();
}

public class TestModel
{
public int Tmp { get; set; }
}
}

 

參考:

  1. Convert(轉型)與Int32(強制轉型)的差別、效能
  2. [C#]Convert.ToInt32()與int.Parse()的差別
  3. [C#]Convert、Parse、TryParse 差異
  4. [C#]Effective C# 條款三: 運算子is或as優於強制轉型