// ==++==
//
//
// Copyright (c) 2002 Microsoft Corporation. All rights reserved.
//
// The use and distribution terms for this software are contained in the file
// named license.txt, which can be found in the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by the
// terms of this license.
//
// You must not remove this notice, or any other, from this software.
//
//
// ==--==
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// Type is the root of all reflection and the Object that represents
// a type inside the system. Type is an abstract base class that allows multiple
// implementations. The system will always provide the subclass __RuntimeType.
// In Reflection all of the __RuntimeXXX classes are created only once per object
// in the system and support == comparisions.
//
// Date: March 98
//
namespace System {
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Reflection.Cache;
using System.Runtime.Remoting;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Security.Permissions;
using CultureInfo = System.Globalization.CultureInfo;
using SignatureHelper = System.Reflection.Emit.SignatureHelper;
using StackCrawlMark = System.Threading.StackCrawlMark;
using DebuggerStepThroughAttribute = System.Diagnostics.DebuggerStepThroughAttribute;
///
[Serializable()]
public abstract class Type : MemberInfo, IReflect
{
// Member filters
///
public static readonly MemberFilter FilterAttribute;
///
public static readonly MemberFilter FilterName;
///
public static readonly MemberFilter FilterNameIgnoreCase;
// mark a parameter as a missing parameter.
///
public static readonly Object Missing = System.Reflection.Missing.Value;
///
public static readonly char Delimiter = '.';
// EmptyTypes is used to indicate that we are looking for someting without any parameters.
///
public readonly static Type[] EmptyTypes = new Type[0];
// The Default binder. We create a single one and expose that.
private static Binder defaultBinder;
// Because the current compiler doesn't support static delegates
// the _Filters object is an object that we create to contain all of
// the filters.
//private static final Type _filterClass = new RuntimeType();
static Type() {
__Filters _filterClass = new __Filters();
FilterAttribute = new MemberFilter(_filterClass.FilterAttribute);
FilterName = new MemberFilter(_filterClass.FilterName);
FilterNameIgnoreCase = new MemberFilter(_filterClass.FilterIgnoreCase);
}
// Prevent from begin created, and allow subclass
// to create.
///
protected Type() {}
// MemberInfo Methods....
// The Member type Field.
///
public override MemberTypes MemberType {
get {return System.Reflection.MemberTypes.TypeInfo;}
}
// Return the class that declared this Field.
///
public override Type DeclaringType {
get {return this;}
}
// Return the class that was used to obtain this field.
///
public override Type ReflectedType {
get {return this;}
}
////////////////////////////////////////////////////////////////////////////////
// This is a static method that returns a Class based upon the name of the class
// (this name needs to be fully qualified with the package name and is
// case-sensitive by default).
////
/************** PLEASE NOTE - THE GETTYPE METHODS NEED TO BE INTERNAL CALLS
// EE USES THE ECALL FRAME TO FIND WHO THE CALLER IS. THIS"LL BREAK IF A METHOD BODY IS ADDED */
///
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern Type GetType(String typeName, bool throwOnError, bool ignoreCase);
///
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern Type GetType(String typeName, bool throwOnError);
///
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern Type GetType(String typeName);
/****************************/
// GetTypeCode
// This method will return a TypeCode for the passed
// type.
///
public static TypeCode GetTypeCode(Type type)
{
if (type == null)
return TypeCode.Empty;
return type.GetTypeCodeInternal();
}
internal virtual TypeCode GetTypeCodeInternal()
{
Type type = this;
if (type is SymbolType)
return TypeCode.Object;
if (type is TypeBuilder)
{
TypeBuilder typeBuilder = (TypeBuilder) type;
if (typeBuilder.IsEnum == false)
return TypeCode.Object;
// if it is an Enum, just let the underlyingSystemType do the work
}
if (type != type.UnderlyingSystemType)
return Type.GetTypeCode(type.UnderlyingSystemType);
return TypeCode.Object;
}
// Property representing the GUID associated with a class.
///
public abstract Guid GUID {
get;
}
// Return the Default binder used by the system.
///
static public Binder DefaultBinder {
get {
// Allocate the default binder if it hasn't been allocated yet.
if (defaultBinder == null)
{
lock(typeof(Type))
{
if (defaultBinder == null)
defaultBinder = new DefaultBinder();
}
}
return defaultBinder;
}
}
// Description of the Binding Process.
// We must invoke a method that is accessable and for which the provided
// parameters have the most specific match. A method may be called if
// 1. The number of parameters in the method declaration equals the number of
// arguments provided to the invocation
// 2. The type of each argument can be converted by the binder to the
// type of the type of the parameter.
//
// The binder will find all of the matching methods. These method are found based
// upon the type of binding requested (MethodInvoke, Get/Set Properties). The set
// of methods is filtered by the name, number of arguments and a set of search modifiers
// defined in the Binder.
//
// After the method is selected, it will be invoked. Accessability is checked
// at that point. The search may be control which set of methods are searched based
// upon the accessibility attribute associated with the method.
//
// The BindToMethod method is responsible for selecting the method to be invoked.
// For the default binder, the most specific method will be selected.
//
// This will invoke a specific member...
///
abstract public Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder,Object target,
Object[] args, ParameterModifier[] modifiers,CultureInfo culture,String[] namedParameters);
///
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
public Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder, Object target, Object[] args, CultureInfo culture)
{
return InvokeMember(name,invokeAttr,binder,target,args,null,culture,null);
}
///
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
public Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder, Object target, Object[] args)
{
return InvokeMember(name,invokeAttr,binder,target,args,null,null,null);
}
// Module Property associated with a class.
///
public abstract Module Module {
get;
}
// Assembly Property associated with a class.
///
public abstract Assembly Assembly {
get;
}
// A class handle is a unique integer value associated with
// each class. The handle is unique during the process life time.
///
public abstract RuntimeTypeHandle TypeHandle {
get;
}
///
public static RuntimeTypeHandle GetTypeHandle(Object o) {
return RuntimeType.InternalGetTypeHandleFromObject(o);
}
///
public static Type GetTypeFromHandle(RuntimeTypeHandle handle)
{
return RuntimeType.GetTypeFromHandleImpl(handle);
}
// Return the fully qualified name. The name does contain the namespace.
///
public abstract String FullName {
get;
}
// Return the name space of the class.
///
public abstract String Namespace {
get;
}
///
public abstract String AssemblyQualifiedName {
get;
}
///
public virtual int GetArrayRank() {
throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
}
// Returns the base class for a class. If this is an interface or has
// no base class null is returned. Object is the only Type that does not
// have a base class.
///
public abstract Type BaseType {
get;
}
// GetConstructor
// This method will search for the specified constructor. For constructors,
// unlike everything else, the default is to not look for static methods. The
// reason is that we don't typically expose the class initializer.
///
public ConstructorInfo GetConstructor(BindingFlags bindingAttr,
Binder binder,
CallingConventions callConvention,
Type[] types,
ParameterModifier[] modifiers)
{
// Must provide some types (Type[0] for nothing)
if (types == null)
throw new ArgumentNullException("types");
for (int i=0;i
public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
{
if (types == null)
throw new ArgumentNullException("types");
for (int i=0;i
public ConstructorInfo GetConstructor(Type[] types)
{
// The arguments are checked in the called version of GetConstructor.
return GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, types, null);
}
///
abstract protected ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr,
Binder binder,
CallingConventions callConvention,
Type[] types,
ParameterModifier[] modifiers);
// GetConstructors()
// This routine will return an array of all constructors supported by the class.
// Unlike everything else, the default is to not look for static methods. The
// reason is that we don't typically expose the class initializer.
///
public ConstructorInfo[] GetConstructors() {
return GetConstructors(BindingFlags.Public | BindingFlags.Instance);
}
///
abstract public ConstructorInfo[] GetConstructors(BindingFlags bindingAttr);
///
public ConstructorInfo TypeInitializer {
get {
return GetConstructorImpl(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
null,
CallingConventions.Any,
Type.EmptyTypes,
null);
}
}
// Return a method based upon the passed criteria. The name of the method
// must be provided, and exception is thrown if it is not. The bindingAttr
// parameter indicates if non-public methods should be searched. The types
// array indicates the types of the parameters being looked for.
///
public MethodInfo GetMethod(String name,
BindingFlags bindingAttr,
Binder binder,
CallingConventions callConvention,
Type[] types,
ParameterModifier[] modifiers)
{
if (name == null)
throw new ArgumentNullException("name");
if (types == null)
throw new ArgumentNullException("types");
for (int i = 0; i < types.Length; i++)
if (types[i] == null)
throw new ArgumentNullException("types");
return GetMethodImpl(name, bindingAttr, binder, callConvention, types, modifiers);
}
///
public MethodInfo GetMethod(String name,
BindingFlags bindingAttr,
Binder binder,
Type[] types,
ParameterModifier[] modifiers)
{
if (name == null)
throw new ArgumentNullException("name");
if (types == null)
throw new ArgumentNullException("types");
for (int i = 0; i < types.Length; i++)
if (types[i] == null)
throw new ArgumentNullException("types");
return GetMethodImpl(name, bindingAttr, binder, CallingConventions.Any, types, modifiers);
}
///
public MethodInfo GetMethod(String name, Type[] types, ParameterModifier[] modifiers)
{
if (name == null)
throw new ArgumentNullException("name");
if (types == null)
throw new ArgumentNullException("types");
for (int i=0;i
public MethodInfo GetMethod(String name,Type[] types)
{
if (name == null)
throw new ArgumentNullException("name");
if (types == null)
throw new ArgumentNullException("types");
for (int i=0;i
public MethodInfo GetMethod(String name, BindingFlags bindingAttr)
{
if (name == null)
throw new ArgumentNullException("name");
return GetMethodImpl(name, bindingAttr, null, CallingConventions.Any, null, null);
}
///
public MethodInfo GetMethod(String name)
{
if (name == null)
throw new ArgumentNullException("name");
return GetMethodImpl(name, Type.DefaultLookup, null, CallingConventions.Any, null, null);
}
///
abstract protected MethodInfo GetMethodImpl(String name,
BindingFlags bindingAttr,
Binder binder,
CallingConventions callConvention,
Type[] types,
ParameterModifier[] modifiers);
// GetMethods
// This routine will return all the methods implemented by the class
///
public MethodInfo[] GetMethods() {
return GetMethods(Type.DefaultLookup);
}
///
abstract public MethodInfo[] GetMethods(BindingFlags bindingAttr);
// GetField
// Get Field will return a specific field based upon name
///
abstract public FieldInfo GetField(String name, BindingFlags bindingAttr);
///
public FieldInfo GetField(String name) {
return GetField(name, Type.DefaultLookup);
}
// GetFields
// Get fields will return a full array of fields implemented by a class
///
public FieldInfo[] GetFields() {
return GetFields(Type.DefaultLookup);
}
///
abstract public FieldInfo[] GetFields(BindingFlags bindingAttr);
// GetInterface
// This method will return an interface (as a class) based upon
// the passed in name.
///
public Type GetInterface(String name) {
return GetInterface(name,false);
}
///
abstract public Type GetInterface(String name, bool ignoreCase);
// GetInterfaces
// This method will return all of the interfaces implemented by a
// class
///
abstract public Type[] GetInterfaces();
// FindInterfaces
// This method will filter the interfaces supported the class
///
public virtual Type[] FindInterfaces(TypeFilter filter,Object filterCriteria)
{
if (filter == null)
throw new ArgumentNullException("filter");
Type[] c = GetInterfaces();
int cnt = 0;
for (int i = 0;i
public EventInfo GetEvent(String name) {
return GetEvent(name,Type.DefaultLookup);
}
///
abstract public EventInfo GetEvent(String name,BindingFlags bindingAttr);
// GetEvents
// This method will return an array of EventInfo. If there are not Events
// an empty array will be returned.
///
virtual public EventInfo[] GetEvents() {
return GetEvents(Type.DefaultLookup);
}
///
abstract public EventInfo[] GetEvents(BindingFlags bindingAttr);
// Return a property based upon the passed criteria. The nameof the
// parameter must be provided.
///
public PropertyInfo GetProperty(String name,BindingFlags bindingAttr,Binder binder,
Type returnType, Type[] types, ParameterModifier[] modifiers)
{
if (name == null)
throw new ArgumentNullException("name");
if (types == null)
throw new ArgumentNullException("types");
return GetPropertyImpl(name,bindingAttr,binder,returnType,types,modifiers);
}
///
public PropertyInfo GetProperty(String name, Type returnType, Type[] types,ParameterModifier[] modifiers)
{
if (name == null)
throw new ArgumentNullException("name");
if (types == null)
throw new ArgumentNullException("types");
return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,types,modifiers);
}
///
public PropertyInfo GetProperty(String name, BindingFlags bindingAttr)
{
if (name == null)
throw new ArgumentNullException("name");
return GetPropertyImpl(name,bindingAttr,null,null,null,null);
}
///
public PropertyInfo GetProperty(String name, Type returnType, Type[] types)
{
if (name == null)
throw new ArgumentNullException("name");
if (types == null)
throw new ArgumentNullException("types");
return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,types,null);
}
///
public PropertyInfo GetProperty(String name, Type[] types)
{
if (name == null)
throw new ArgumentNullException("name");
if (types == null)
throw new ArgumentNullException("types");
return GetPropertyImpl(name,Type.DefaultLookup,null,null,types,null);
}
///
public PropertyInfo GetProperty(String name, Type returnType)
{
if (name == null)
throw new ArgumentNullException("name");
if (returnType == null)
throw new ArgumentNullException("returnType");
return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,null,null);
}
///
public PropertyInfo GetProperty(String name)
{
if (name == null)
throw new ArgumentNullException("name");
return GetPropertyImpl(name,Type.DefaultLookup,null,null,null,null);
}
///
abstract protected PropertyInfo GetPropertyImpl(String name, BindingFlags bindingAttr,Binder binder,
Type returnType, Type[] types, ParameterModifier[] modifiers);
// GetProperties
// This method will return an array of all of the properties defined
// for a Type.
///
abstract public PropertyInfo[] GetProperties(BindingFlags bindingAttr);
///
public PropertyInfo[] GetProperties()
{
return GetProperties(Type.DefaultLookup);
}
// GetNestedTypes()
// This set of method will return any nested types that are found inside
// of the type.
///
public Type[] GetNestedTypes()
{
return GetNestedTypes(Type.DefaultLookup);
}
///
abstract public Type[] GetNestedTypes(BindingFlags bindingAttr);
// GetNestedType()
///
public Type GetNestedType(String name)
{
return GetNestedType(name,Type.DefaultLookup);
}
///
abstract public Type GetNestedType(String name, BindingFlags bindingAttr);
// GetMember
// This method will return all of the members which match the specified string
// passed into the method
///
public MemberInfo[] GetMember(String name) {
return GetMember(name,Type.DefaultLookup);
}
///
virtual public MemberInfo[] GetMember(String name, BindingFlags bindingAttr)
{
return GetMember(name,MemberTypes.All,bindingAttr);
}
///
virtual public MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
{
throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
}
// GetMembers
// This will return a Member array of all of the members of a class
///
public MemberInfo[] GetMembers() {
return GetMembers(Type.DefaultLookup);
}
///
abstract public MemberInfo[] GetMembers(BindingFlags bindingAttr);
// GetDefaultMembers
// This will return a MemberInfo that has been marked with the
// DefaultMemberAttribute
///
public virtual MemberInfo[] GetDefaultMembers()
{
// See if we have cached the default member name
String defaultMember = (String)this.Cache[CacheObjType.DefaultMember];
if (defaultMember == null) {
// Get all of the custom attributes
Object[] attrs = GetCustomAttributes(typeof(DefaultMemberAttribute), true);
// We assume that there is only one DefaultMemberAttribute (Allow multiple = false)
if (attrs.Length > 1)
throw new ExecutionEngineException(Environment.GetResourceString("ExecutionEngine_InvalidAttribute"));
if (attrs.Length == 0)
return new MemberInfo[0];
defaultMember = ((DefaultMemberAttribute)attrs[0]).MemberName;
this.Cache[CacheObjType.DefaultMember] = defaultMember;
}
MemberInfo[] members = GetMember(defaultMember);
if (members == null)
members = new MemberInfo[0];
return members;
}
internal virtual String GetDefaultMemberName() {
// See if we have cached the default member name
String defaultMember = (String)this.Cache[CacheObjType.DefaultMember];
if (defaultMember == null)
{
Object[] attrs = GetCustomAttributes(typeof(DefaultMemberAttribute), true);
// We assume that there is only one DefaultMemberAttribute (Allow multiple = false)
if (attrs.Length > 1)
throw new ExecutionEngineException(Environment.GetResourceString("ExecutionEngine_InvalidAttribute"));
if (attrs.Length == 0)
return null;
defaultMember = ((DefaultMemberAttribute)attrs[0]).MemberName;
this.Cache[CacheObjType.DefaultMember] = defaultMember;
}
return defaultMember;
}
// FindMembers
// This will return a filtered version of the member information
///
public virtual MemberInfo[] FindMembers(MemberTypes memberType,BindingFlags bindingAttr,MemberFilter filter,Object filterCriteria)
{
// Define the work arrays
MethodInfo[] m = null;
ConstructorInfo[] c = null;
FieldInfo[] f = null;
PropertyInfo[] p = null;
EventInfo[] e = null;
Type[] t = null;
int i = 0;
int cnt = 0; // Total Matchs
// Check the methods
if ((memberType & System.Reflection.MemberTypes.Method) != 0) {
m = GetMethods(bindingAttr);
if (filter != null) {
for (i=0;i
public TypeAttributes Attributes {
get {return GetAttributeFlagsImpl();}
}
///
public bool IsNotPublic {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic);}
}
///
public bool IsPublic {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.Public);}
}
///
public bool IsNestedPublic {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic);}
}
///
public bool IsNestedPrivate {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate);}
}
///
public bool IsNestedFamily {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily);}
}
///
public bool IsNestedAssembly {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly);}
}
///
public bool IsNestedFamANDAssem {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem);}
}
///
public bool IsNestedFamORAssem{
get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem);}
}
///
public bool IsAutoLayout {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout);}
}
///
public bool IsLayoutSequential {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout);}
}
///
public bool IsExplicitLayout {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout);}
}
///
public bool IsClass {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class && !IsSubclassOf(Type.valueType));}
}
///
public bool IsInterface {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface);}
}
///
public bool IsValueType {
get {return IsValueTypeImpl();}
}
///
public bool IsAbstract {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.Abstract) != 0);}
}
///
public bool IsSealed {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.Sealed) != 0);}
}
///
public bool IsEnum {
get {return IsSubclassOf(Type.enumType);}
}
///
public bool IsSpecialName {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.SpecialName) != 0);}
}
///
public bool IsImport {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.Import) != 0);}
}
///
public bool IsSerializable {
get {return (((GetAttributeFlagsImpl() & TypeAttributes.Serializable) != 0) ||
(this.QuickSerializationCastCheck()));}
}
private bool QuickSerializationCastCheck() {
Type c = this.UnderlyingSystemType;
while (c!=null) {
if (c==typeof(Enum) || c==typeof(Delegate)) {
return true;
}
c = c.BaseType;
}
return false;
}
///
public bool IsAnsiClass {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass);}
}
///
public bool IsUnicodeClass {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass);}
}
///
public bool IsAutoClass {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass);}
}
// These are not backed up by attributes. Instead they are implemented
// based internally.
///
public bool IsArray {
get {return IsArrayImpl();}
}
///
public bool IsByRef {
get {return IsByRefImpl();}
}
///
public bool IsPointer {
get {return IsPointerImpl();}
}
///
public bool IsPrimitive {
get {return IsPrimitiveImpl();}
}
///
public bool IsCOMObject {
get {return IsCOMObjectImpl();}
}
internal bool IsGenericCOMObject {
get {
if (this is RuntimeType)
return ((RuntimeType)this).IsGenericCOMObjectImpl();
else
return false;
}
}
///
public bool HasElementType {
get {return HasElementTypeImpl();}
}
///
public bool IsContextful {
get {return IsContextfulImpl();}
}
///
public bool IsMarshalByRef {
get {return IsMarshalByRefImpl();}
}
internal bool HasProxyAttribute {
get {return HasProxyAttributeImpl();}
}
// Protected routine to determine if this class represents a value class
///
protected virtual bool IsValueTypeImpl() {
Type type = this;
if (type == Type.valueType || type == Type.enumType)
return false;
return IsSubclassOf(Type.valueType);
}
// Protected routine to get the attributes.
///
abstract protected TypeAttributes GetAttributeFlagsImpl();
// Protected routine to determine if this class represents an Array
///
abstract protected bool IsArrayImpl();
// Protected routine to determine if this class is a ByRef
///
abstract protected bool IsByRefImpl();
// Protected routine to determine if this class is a Pointer
///
abstract protected bool IsPointerImpl();
// Protected routine to determine if this class represents a primitive type
///
abstract protected bool IsPrimitiveImpl();
// Protected routine to determine if this class represents a COM object
///
abstract protected bool IsCOMObjectImpl();
// Protected routine to determine if this class is contextful
///
protected virtual bool IsContextfulImpl(){
return typeof(ContextBoundObject).IsAssignableFrom(this);
}
// Protected routine to determine if this class is marshaled by ref
///
protected virtual bool IsMarshalByRefImpl(){
return typeof(MarshalByRefObject).IsAssignableFrom(this);
}
internal virtual bool HasProxyAttributeImpl()
{
// We will override this in RuntimeType
return false;
}
///
abstract public Type GetElementType();
///
abstract protected bool HasElementTypeImpl();
// Return the underlying Type that represents the IReflect Object. For expando object,
// this is the (Object) IReflectInstance.GetType(). For Type object it is this.
///
public abstract Type UnderlyingSystemType {
get;
}
// IsLoaded
// This indicates if the class has been loaded into the runtime.
internal virtual bool IsLoaded()
{
return true;
}
// Returns true of this class is a true subclass of c. Everything
// else returns false. If this class and c are the same class false is
// returned.
//
///
public virtual bool IsSubclassOf(Type c)
{
Type p = this;
if (p == c)
return false;
while (p != null) {
if (p == c)
return true;
p = p.BaseType;
}
return false;
}
// Returns true if the object passed is assignable to an instance of this class.
// Everything else returns false.
//
///
public virtual bool IsInstanceOfType(Object o)
{
if (o == null)
return false;
// For transparent proxies we have to check the cast
// using remoting specific facilities.
if(RemotingServices.IsTransparentProxy(o)) {
return (null != RemotingServices.CheckCast(o, this));
}
if (IsInterface && o.GetType().IsCOMObject) {
if (this is RuntimeType)
return ((RuntimeType) this).SupportsInterface(o);
}
return IsAssignableFrom(o.GetType());
}
// Returns true if an instance of Type c may be assigned
// to an instance of this class. Return false otherwise.
//
///
public virtual bool IsAssignableFrom(Type c)
{
if (c == null)
return false;
try {
RuntimeType fromType = c.UnderlyingSystemType as RuntimeType;
RuntimeType toType = this.UnderlyingSystemType as RuntimeType;
if (fromType == null || toType == null)
{
// special case for TypeBuilder
TypeBuilder fromTypeBuilder = c as TypeBuilder;
if (fromTypeBuilder == null)
{
return false;
}
if (TypeBuilder.IsTypeEqual(this, c))
return true;
// If fromTypeBuilder is a subclass of this class, then c can be cast to this type.
if (fromTypeBuilder.IsSubclassOf(this))
return true;
if (this.IsInterface == false)
{
return false;
}
// now is This type a base type on one of the interface impl?
Type[] interfaces = fromTypeBuilder.GetInterfaces();
for (int i = 0; i < interfaces.Length; i++)
{
if (TypeBuilder.IsTypeEqual(interfaces[i], this))
return true;
if (interfaces[i].IsSubclassOf(this))
return true;
}
return false;
}
bool b = RuntimeType.CanCastTo(fromType, toType);
return b;
}
catch (ArgumentException) {}
// Check for interfaces
if (IsInterface) {
Type[] ifaces = c.GetInterfaces();
for (int i=0;i
public override String ToString()
{
return "Type: "+Name;
}
// This method will return an array of classes based upon the array of
// types.
///
public static Type[] GetTypeArray(Object[] args) {
if (args == null)
throw new ArgumentNullException("args");
Type[] cls = new Type[args.Length];
for (int i=0;i
public override bool Equals(Object o) {
if (o == null)
return false;
if (!(o is Type))
return false;
return (this.UnderlyingSystemType == ((Type) o).UnderlyingSystemType);
}
///
public bool Equals(Type o) {
if (o == null)
return false;
return (this.UnderlyingSystemType == o.UnderlyingSystemType);
}
///
public override int GetHashCode()
{
Type SystemType = UnderlyingSystemType;
if (SystemType != this)
return SystemType.GetHashCode();
return base.GetHashCode();
}
// GetInterfaceMap
// This method will return an interface mapping for the interface
// requested. It will throw an argument exception if the Type doesn't
// implemenet the interface.
///
public virtual InterfaceMapping GetInterfaceMap(Type interfaceType)
{
throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
}
// This is used by Remoting
internal static Type ResolveTypeRelativeTo(String typeName, Type serverType)
{
return ResolveTypeRelativeTo(typeName, 0, typeName.Length, serverType);
} // ResolveTypeRelativeTo
// This is used by Remoting
internal static Type ResolveTypeRelativeTo(String typeName, int offset, int count, Type serverType)
{
Type type = ResolveTypeRelativeToBaseTypes(typeName, offset, count, serverType);
if (type == null)
{
// compare against the interface list
// GetInterfaces() returns a complete list of interfaces this type supports
Type[] interfaces = serverType.GetInterfaces();
foreach (Type iface in interfaces)
{
String ifaceTypeName = iface.FullName;
if (ifaceTypeName.Length == count)
{
if (String.CompareOrdinal(typeName, offset, ifaceTypeName, 0, count) == 0)
{
return iface;
}
}
}
}
return type;
} // ResolveTypeRelativeTo
// This is used by Remoting
internal static Type ResolveTypeRelativeToBaseTypes(String typeName, int offset, int count, Type serverType)
{
// typeName is excepted to contain the full type name
// offset is the start of the full type name within typeName
// count us the number of characters in the full type name
// serverType is the type of the server object
if ((typeName == null) || (serverType == null))
return null;
String serverTypeName = serverType.FullName;
if (serverTypeName.Length == count)
{
if (String.CompareOrdinal(typeName, offset, serverTypeName, 0, count) == 0)
{
return serverType;
}
}
return ResolveTypeRelativeToBaseTypes(typeName, offset, count, serverType.BaseType);
} // ResolveTypeRelativeTo
// private convenience data
private const BindingFlags DefaultLookup = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
private static readonly Type valueType = typeof(System.ValueType);
private static readonly Type enumType = typeof(System.Enum);
private static readonly Type objectType = typeof(System.Object);
}
}