2016-04-13 21 views
2

"is" operatörüne bir dizi tür iletmenin bir yolu var mı?C# birden çok türe karşı nesne nesnesini kontrol edin

Bir nesneyi birden çok türe karşı kontrol etme sözdizimini basitleştirmeye çalışıyorum.

şey gibi:

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

Ancak bu şu kullanımını gerektirecektir:

if(X is {int,float}) 

veya

if(X.IsOfType(int,float)) 
:

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

ben böyle bir şey yapmak istiyorum

hatta

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

hepsi imkansız olduğunu düşünüyorum.

+2

Yapmanız gereken bir kod yazıyorsanız * temel * türlerine karşı bu tür bir tür denetimi, CLR'nin kendisi ile kullanılan genel yaklaşım, ['Type.GetTypeCode'] 'da (' https://msdn.microsoft.com/library/system 'adresindeki' switch '). type.gettypecode). Bunu temel olmayan türlere karşı çok fazla buluyorsanız, kodunuzda muhtemelen bunun için bir kısayola ihtiyaç duyduğu bir yanlışlık vardır. –

+0

@JeroenMostert hakkında daha fazla yorum için, [türün sayısal olup olmadığına bakın] (https://stackoverflow.com/questions/1749966/c-sharp-how-to-determine-whether-a-type-is- bir sayı). – ryanyuyu

+0

Sadece IsNumeric uzantısı işlevi oluşturun. Nesneyi çok sayıda rastgele türe karşı kontrol etmeniz gerçekten olası değildir. – Evk

cevap

0

Türleri genel argümanlar olarak iletmekten başka bir şey yoksa, bir çözüm var. Ne yazık ki, C#, variadic jenerikleri desteklemiyor. Her bir genel aritmin işlevini tanımlamanız gerekir.

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'den fazla türe gereksiniminiz olduğundan şüphe duyuyorum; ancak, daha fazla aşırı yükleme tanımlayın.

+0

Ne aradığımı değil ama kesinlikle problem için sınırlı bir çözüm. –

+0

İlk çözümüm, ancak typeof(): genel statik bool IsAnyOf (bu nesne Obj, params Türü [] Türleri) { foreach'in (Tür Türleri Türünde) yeniden kullanılmasından dolayı kullanıldığında hala uzun sonuçlar verir. eğer (Obj Türü) doğruysa; yanlış döndürür; } –

+0

kullanımı: ctxScript.Visible =! NSeçected.IsAnyOf (typeof (TablesNode) typeof (ViewsNode) typeof (ProcedureNode) typeof (UserTableTypesNode) typeof (FunctionsNode) typeof (ServerNode) typeof (DatabaseNode)); –

0

"Seçilmiş" çözümüm, nesne türü adına göre doğrulamak için kullanışlı "In" uzantı işlevimi kullanmaktı.

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; 
    } 

Kullanımı:

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

O can deli görünüyor, ama şu Akıcı sözdizimini kullanabilirsiniz: aşağıdaki gibi

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

akıcı-sözdizimi uygulanır:

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(); } 
    } 
} 
İlgili konular