2013-08-02 25 views
4

我有一定的代碼段,需要執行,如果數據類型的變量有一定的基礎,匹配type.Currently我這樣做是使用的if-else循環如何實現型開關

前:

if(a is float) 
    { 
    // do something here 
    } 
    else if (a is int) 
    { 
    // do something here 
    } 
    else if (a is string) 
    { 
    // do something here 
    } 

由於我有太多的類型與我必須比較,使用如果其他很笨拙。 由於C#不允許類型切換,有沒有其他方法可以做到這一點?

+0

如何查看var關鍵字,那樣變量var就是那個對象的類型。 – lloydom

+0

switch(a.getType()。ToString()) – StampedeXV

+0

@StampedeXV認真嗎?我的意思是,沒有冒犯,但*不寒而慄* – PoByBolek

回答

5

重構代碼,並使用方法重載

void SomeCode() 
{ 
    ... 
    Action(3.0f); // calls float overload 
    Action("hello"); // calls string overload 
    ... 
} 

void Action(float a) 
{ 
    ... 
} 
void Action(int a) 
{ 
    ... 
} 
void Action(string a) 
{ 
    ... 
} 

編輯:
通過使用dynamic關鍵字(.NET 4)是這樣工作的(全控制檯應用程序):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      SomeCode(); 
     } 

     static void SomeCode() 
     { 
      object o = null; 
      switch (new Random().Next(0, 3)) 
      { 
       case 0: 
        o = 3.0f; 
        break; 
       case 1: 
        o = 3.0d; 
        break; 
       case 2: 
        o = "hello"; 
        break; 
      } 
      Action((dynamic)o); // notice dynamic here 
     } 

     static void Action(dynamic a) 
     { 
      Console.WriteLine("object"); 
     } 

     static void Action(float a) 
     { 
      Console.WriteLine("float"); 
     } 
     static void Action(int a) 
     { 
      Console.WriteLine("int"); 
     } 
     static void Action(string a) 
     { 
      Console.WriteLine("string"); 
     } 
    } 
} 
+1

這是方法重載,而不是運算符重載我相信... – Chris

+4

雖然我同意這是一個更好的方式做事,但它可能不適用如果在編譯時不知道'a'的類型(例如它的類型爲'對象') –

+0

@ChrisSinclair:我認爲理所當然地認爲'a'被鍵入到'object',否則在問題中顯示的檢查沒有任何意義。 –

0

我的解決方案是不是比你的不同,但我沒有這樣說:

while(true){ 
    var typeOfVarToCheck = a.GetType(); // a comes from Op's Code 
    if(typeOfVarToCheck==typeof(type1)){ 
     //Do Something 
     break; 
    } 
    if(typeOfVarToCheck==typeof(type2)){ 
     //Do Something 
     break; 
    } 
    //Do default 
    break; 
} 
+1

您爲了避免else關鍵字而阻止循環的while循環?重點是什麼 ? –

+0

你爲什麼要這樣做而不是'if'和'else'?另外,你的條件'type1'和'type2'看起來像什麼?這就是要求的。 –

+0

唯一的區別是審美,更容易查看,因爲它看起來更接近switch語句格式(但我認爲這是一種主觀的東西)。這就是爲什麼我說它和OP的解決方案沒有多大區別。我將編輯帖子以顯示類型檢查條件 – JTMon

2

您可以創建一個Dictionary<Type, Action<object>>和存儲從aGetType method的類型(返回值與執行要取其代碼代表一起運行一個給定的類型。

例如,看看這個:

private readonly Dictionary<Type, Action<object>> typeActions = new Dictionary<Type, Action<object>>() 
{ 
    { typeof(int), (a) => { Console.WriteLine(a.ToString() + " is an integer!"); } }, 
    { typeof(float), (a) => { Console.WriteLine(a.ToString() + " is a single-precision floating-point number!"); } } 
}; 

本詞典然後可以在其他地方在你的代碼中使用:

Action<object> action; 
if (typeActions.TryGetValue(a.GetType(), out action)) { 
    action(a); 
} 

注意,你仍然要內施放a爲適當的類型你的行爲。

編輯:由於Chris正確指出,如果a屬於註冊類型的子類,這將不會識別a.GetType()。如果需要包括,你將不得不走的類型層次結構:如果你需要覆蓋泛型類型和/或接口

Action<object> action = null; 
for (Type t = a.GetType(); t = t.BaseType; t != null) { 
    if (typeActions.TryGetValue(t, out action)) { 
     break; 
    } 
} 
if (action != null) { 
    action(a); 
} 

,這是可行的,太多,但代碼將成爲穩步更加複雜。

+1

這個問題的唯一警告是利用'is'運算符來匹配派生類型和接口,而這隻會匹配確切的類型。 (給出的問題表示'int','float','string',這可能不是問題) –

+0

@ChrisSinclair:謝謝,你是對的 - 我已經編輯了我的回覆來覆蓋這種情況。 –

+0

如果你願意,你也可以翻轉它並迭代字典類型元素並利用['Type.IsAssignableFrom'](http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom.aspx)檢查所有派生類型和接口;基本上是一個「is」檢查。 –

0

您應該將類​​型轉換爲字符串。

var typeObj = //Value... 

     switch (typeObj.GetType().ToString()) 
     { 
      case "System.Int32": 
       //Some Code 
      case "System.String": 
       //Some Code 
      default: 
       break; 
     } 
+2

但是,那麼如何處理派生類型或接口呢? –

+0

如果您需要切換派生對象,最好使用方法重載。你也可以使用commom屬性實現一個接口,並在類聲明中使用這個接口,這樣你就可以切換這個屬性。 –