C#对照多种类型检查对象类型
是否有方法将类型数组传递给“IS”运算符 我试图简化针对多种类型检查对象的语法 比如: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
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
属性的公共基础。这允许您添加新节点类型,而无需在代码中查找所有需要添加新节点知识的位置。