Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#对照多种类型检查对象类型_C#_Arrays_Generics - Fatal编程技术网

C#对照多种类型检查对象类型

C#对照多种类型检查对象类型,c#,arrays,generics,C#,Arrays,Generics,是否有方法将类型数组传递给“IS”运算符 我试图简化针对多种类型检查对象的语法 比如: public static function bool IsOfType(object Obj,params Type[] Types) if(X is {int,float}) 但是,这需要以下用法: if(X.IsOfType(typeof(int),typeof(float)) {...} 我想做一些类似的事情: public static function bool IsOfType(objec

是否有方法将类型数组传递给“IS”运算符

我试图简化针对多种类型检查对象的语法

比如:

public static function bool IsOfType(object Obj,params Type[] Types)
if(X is {int,float})
但是,这需要以下用法:

if(X.IsOfType(typeof(int),typeof(float))
{...}
我想做一些类似的事情:

public static function bool IsOfType(object Obj,params Type[] Types)
if(X is {int,float})

甚至

public static bool ISOfType<T[]>(this object Obj){...}
if(X.ISOfType<int,float>())
publicstaticboolsoftype(这个对象Obj){…}
if(X.ISOfType())

我认为它们都是不可能的。

如果您同意将类型作为泛型参数传递,那么有一个解决方案。不幸的是,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;
公共静态bool类型(此对象obj)=>obj为T;
公共静态布尔类型(该对象obj)=>obj是T1 | | obj是T2;
公共静态布尔类型(此对象obj)=>obj为T1 | | | obj为T2 | | obj为T3;
公共静态布尔类型(此对象obj)=>obj为T1 | | | obj为T2 | | obj为T3 | | obj为T4;
公共静态布尔类型(此对象obj)=>obj为T1 | | | obj为T2 | | obj为T3 | | obj为T4 | | obj为T5;
公共静态布尔类型(此对象obj)=>obj为T1 | | | obj为T2 | | obj为T3 | | obj为T4 | | obj为T5 | | obj为T6;
公共静态布尔类型(此对象obj)=>obj为T1 | | | obj为T2 | | obj为T3 | | obj为T4 | | obj为T5 | | obj为T6 | | obj为T7;
公共静态布尔类型(该对象obj)=>obj为T1 | | | obj为T2 | | obj为T3 | | obj为T4 | | obj为T5 | | obj为T6 | | obj为T7 | obj为T8;
我怀疑您将需要8种以上的类型,但如果需要,只需定义更多重载。

我选择的解决方案是使用我方便的“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) };

    }

它看起来很疯狂,但您可以使用以下流畅的语法:

object someInstance = 5.0;
if(someInstance
    .Is<int>()
    .Or<double>()) {
    // ...
}
objectsomeinstance=5.0;
如果(某物)
.Is()
.或(){
// ...
}
在这里,fluent语法的实现如下:

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(); }
    }
}
静态类FluentIs{
公共静态IsResult为(此对象目标){
返回新的IsResult(target,()=>target为T);
}
公共静态IsResult或(此IsResult prev){
返回新IsResult(上一个(v,x)=>v | |(x是T));
}
公共类IsResult{
Func值;
目标对象;
内部IsResult(IsResult r,Func getValue):
这(r.target,()=>getValue(r.value(),r.target)){
}
内部IsResult(对象目标,函数值){
this.target=目标;
这个值=值;
}
//布尔算子
公共静态布尔运算符true(IsResult r){return r.value();}
公共静态布尔运算符false(IsResult r){return!r.value();}
}
}

如果您编写的代码必须针对基本类型执行大量类型检查,则CLR本身使用的常用方法是打开
开关。如果您发现自己经常针对非基本类型执行此操作,那么您的代码可能有问题,首先需要对其进行简化。为了进一步@jeroenmoster注释,以下是方法。只需创建IsNumeric扩展函数。您不太可能真的需要针对许多任意类型检查对象。这不是我想要的,但肯定是该问题的有限解决方案。我最初的解决方案如下,但由于重复使用typeof():public static bool IsAnyOf(this object Obj,params Type[]types){foreach(Type-in-Types)if(Obj是Type)返回true;返回false;}用法:ctxScript.Visible=!nSelected.IsAnyOf(typeof(tableNode)、typeof(ViewsNode)、typeof(ProcedureNode)、typeof(UserTableTypesNode)、typeof(FunctionsNode),typeof(服务器节点),typeof(数据库节点))@JeffHolodnak:对于您正在做的事情,经典的解决方案是访问者,为类提供一个带有虚拟
ScriptOptionVisible
属性的公共基础。这允许您添加新节点类型,而无需在代码中查找所有需要添加新节点知识的位置。