2016-04-13 56 views
2

有沒有辦法將類型數組傳遞給「is」運算符?C#檢查多種類型的對象類型

我試圖簡化檢查對多種類型的對象的語法。

喜歡的東西:

public static function bool IsOfType(object Obj,params Type[] Types) 

但這會需要以下用法:

if(X.IsOfType(typeof(int),typeof(float)) 
{...} 

我想這樣做:

if(X is {int,float}) 

if(X.IsOfType(int,float)) 

甚至

public static bool ISOfType<T[]>(this object Obj){...} 
if(X.ISOfType<int,float>()) 

我覺得他們都是不可能的。

+2

如果您正在編寫必須執行的代碼很多類型檢查都是針對* basic *類型的,這與CLR本身一起使用的常用方法是在['Type.GetTypeCode'](https://msdn.microsoft.com/library/system。 type.gettypecode)。如果你發現自己對非基本類型做了很多事情,那麼你的代碼可能有些問題,首先它需要一個簡寫。 –

+0

爲了進一步@JeroenMostert評論,這是如何[檢查類型是數字](https://stackoverflow.com/questions/1749966/c-sharp-how-to-determine-whether-a-type-is-一個號碼)。 – ryanyuyu

+0

只需創建IsNumeric擴展功能即可。你不太可能真的需要檢查許多任意類型的對象。 – Evk

回答

0

如果可以將類型作爲泛型參數傳遞,那麼有一個解決方案。不幸的是,C#不支持可變泛型。您必須爲每個通用元素定義函數。

public static bool IsOfType<T>(this object obj) => obj is T; 
public static bool IsOfType<T1, T2>(this object obj) => obj is T1 || obj is T2; 
public static bool IsOfType<T1, T2, T3>(this object obj) => obj is T1 || obj is T2 || obj is T3; 
public static bool IsOfType<T1, T2, T3, T4>(this object obj) => obj is T1 || obj is T2 || obj is T3 || obj is T4; 
public static bool IsOfType<T1, T2, T3, T4, T5>(this object obj) => obj is T1 || obj is T2 || obj is T3 || obj is T4 || obj is T5; 
public static bool IsOfType<T1, T2, T3, T4, T5, T6>(this object obj) => obj is T1 || obj is T2 || obj is T3 || obj is T4 || obj is T5 || obj is T6; 
public static bool IsOfType<T1, T2, T3, T4, T5, T6, T7>(this object obj) => obj is T1 || obj is T2 || obj is T3 || obj is T4 || obj is T5 || obj is T6 || obj is T7; 
public static bool IsOfType<T1, T2, T3, T4, T5, T6, T7, T8>(this object obj) => obj is T1 || obj is T2 || obj is T3 || obj is T4 || obj is T5 || obj is T6 || obj is T7 || obj is T8; 

我懷疑你會需要超過8種類型,但如果你這樣做,只需定義更多的重載。

+0

不是我正在尋找的,但絕對是一個有限的解決方案。 –

+0

我最初的解決方案如下,但由於typeof()的重用,在使用它時仍會產生很長的時間: public static bool IsAnyOf(this object Obj,params Type [] Types) foreach(Type Type in Types)如果(Obj是Type)返回true; 返回false; } –

+0

用法:ctxScript.Visible =!n已選中。IsAnyOf(typeof運算(TablesNode) 的typeof(ViewsNode) 的typeof(ProcedureNode) 的typeof(UserTableTypesNode) 的typeof(FunctionsNode) 的typeof(ServerNode) 的typeof(DatabaseNode)); –

0

我的「選擇」解決方案是使用我方便的「In」擴展函數根據對象類型名稱進行驗證。

public static bool IsAnyOf(this object Obj,params string[] TypeNames) 
    { 
     return Obj.GetType().Name.In(TypeNames); 
    } 
    public static bool In(this string Needle,params string [] Haystack) 
    { 
     foreach (string straw in Haystack) 
      if (straw == Needle) 
       return true; 
     return false; 
    } 

用法:

public static void CheckAll(this TreeNode Node) 
    { 
     foreach(TreeNode Child in Node.Nodes) 
     { 
      if(Child.GetType().Name.In("ChildTablesNode","ChildTableNode")) 
      { 
       Child.Checked = Node.Checked; 
       Child.CheckAll(); 
      } 
     } 
    } 

    private void ctxTree_Opening(object sender, CancelEventArgs e) 
    { 
     TreeNode nSelected = Tree.SelectedNode; 

     ctxScript.Visible = !nSelected.IsAnyOf("TablesNode" 
      , "ViewsNode" 
      , "ProceduresNode" 
      , "UserTableTypesNode" 
      , "FunctionsNode" 
      , "ServerNode" 
      , "DatabaseNode" 
      , "ColumnsNode" 
      , "ColumnNode" 
      , "TriggersNode"); 

     Type[] x = { typeof(int) }; 

    } 
0

它可以看起來很瘋狂,但是你可以使用以下流利的語法:如下

object someInstance = 5.0; 
if(someInstance 
    .Is<int>() 
    .Or<double>()) { 
    // ... 
} 

這裏流利的語法實現:

static class FluentIs { 
    public static IsResult Is<T>(this object target) { 
     return new IsResult(target,() => target is T); 
    } 
    public static IsResult Or<T>(this IsResult prev) { 
     return new IsResult(prev, (v, x) => v || (x is T)); 
    } 
    public class IsResult { 
     Func<bool> value; 
     object target; 
     internal IsResult(IsResult r, Func<bool, object, bool> getValue) : 
      this(r.target,() => getValue(r.value(), r.target)) { 
     } 
     internal IsResult(object target, Func<bool> value) { 
      this.target = target; 
      this.value = value; 
     } 
     // bool Operators 
     public static bool operator true(IsResult r) { return r.value(); } 
     public static bool operator false(IsResult r) { return !r.value(); } 
    } 
}