[英]C# check object type against multiple types
有没有办法将类型数组传递给“is”运算符?
我正在尝试简化针对多种类型检查对象的语法。
就像是:
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>())
我认为它们都是不可能的。
使用 C# 10,您可以使用模式匹配来测试对象的多种类型。
例子:
public bool TestObject<T>(T obj)
{
if (obj is not null and (int or float or uint))
{
// obj is not null and guaranteed to be an int, float or uint
}
}
示例 2(如果您想使用该值):
public bool TestIntOrFloat<T>(T obj)
{
if (obj is not (int or float))
{
// obj is neither int or float
}
else if (obj is int i)
{
// obj is an integer and can be used with the variable 'i'
}
else if (obj is float f)
{
// obj is a floating number and can be used with the variable 'f'
}
}
如果您可以将类型作为通用参数传递,那么有一个解决方案。 不幸的是,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 种类型,但如果你这样做,只需定义更多的重载。
它看起来很疯狂,但您可以使用以下 Fluent 语法:
object someInstance = 5.0;
if(someInstance
.Is<int>()
.Or<double>()) {
// ...
}
这里 fluent-syntax 实现如下:
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(); }
}
}
我的“选择”解决方案是使用我方便的“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) };
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.