is和as
is关键字可以确定对象实例或表达式结果是否可转换为指定类型。基本语法:
expr is type
如果满足以下条件,则 is 语句为 true:
- expr 是与 type 具有相同类型的一个实例。
- expr 是派生自 type 的类型的一个实例。 换言之,expr 结果可以向上转换为 type 的一个实例。
- expr 具有属于 type 的一个基类的编译时类型,expr 还具有属于 type 或派生自 type 的运行时类型。 变量的编译时类型是其声明中定义的变量类型。 变量的运行时类型是分配给该变量的实例类型。
- expr 是实现 type 接口的类型的一个实例。
代码:
using System; public class Class1 : IFormatProvider { public object GetFormat(Type t) { if (t.Equals(this.GetType())) return this; return null; } } public class Class2 : Class1 { public int Value { get; set; } } public class Example { public static void Main() { var cl1 = new Class1(); Console.WriteLine(cl1 is IFormatProvider); //True Console.WriteLine(cl1 is Object); //True Console.WriteLine(cl1 is Class1); //True Console.WriteLine(cl1 is Class2); //True Console.WriteLine(); var cl2 = new Class2(); Console.WriteLine(cl2 is IFormatProvider); //True Console.WriteLine(cl2 is Class2); //True Console.WriteLine(cl2 is Class1); //True Console.WriteLine(); Class1 cl = cl2; Console.WriteLine(cl is Class1); //True Console.WriteLine(cl is Class2); //True } }
as运算符类似于转换运算。如果无法进行转换,则 as 会返回 null,而不是引发异常。基本语法:
expr as type
等效
expr is type ? (type)expr : (type)null
可以尝试转换,根据转换的成功与否判断类的派生关系。
参考至:
- https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/is
- https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/as
Type.IsSubclassOf 和 Type.IsAssignableFrom
Type.IsSubclassOf 确定当前 Type 是否派生自指定的 Type。
[ComVisibleAttribute(true)] public virtual bool IsSubclassOf( Type c )
如果当前 Type 派生于 c,则为 True;否则为 false。 如果 当前Type 和 c 相等,此方法也返回 True。
但是IsSubclassOf方法不能用于确定接口是否派生自另一个接口,或是否类实现的接口。
Type.IsAssignableFrom 确定指定类型的实例是否可以分配给当前类型的实例。
public virtual bool IsAssignableFrom( Type c )
如果满足下列任一条件,则为 true:
- c 且当前实例表示相同类型。
- c 是从当前实例直接或间接派生的。 c 它继承自的当前实例; 如果直接从当前实例派生 c 如果它继承自一个或多个从继承类的当前实例的一系列的当前实例中间接派生。
- 当前实例是一个 c 实现的接口。
- c 是一个泛型类型参数,并且当前实例表示 c 的约束之一。
代码:
using System; public interface IInterface { void Display(); } public class Class1 { } public class Implementation :Class1, IInterface { public void Display() { Console.WriteLine("The implementation..."); } } public class Example { public static void Main() { Console.WriteLine("Implementation is a subclass of IInterface: {0}", typeof(Implementation).IsSubclassOf(typeof(IInterface))); //False Console.WriteLine("Implementation subclass of Class1: {0}", typeof(Implementation).IsSubclassOf(typeof(Class1))); //True Console.WriteLine("IInterface is assignable from Implementation: {0}", typeof(IInterface).IsAssignableFrom(typeof(Implementation))); //True Console.WriteLine("Class1 is assignable from Implementation: {0}", typeof(Class1).IsAssignableFrom(typeof(Implementation))); //True } }
可以使用 Type.IsSubclassOf 判断类的派生, 使用 Type.IsAssignableFrom 判断类的派生和接口继承。
参考至: