Type.IsAssignableFrom Method
Determines whether an instance of the current Type can be assigned from an instance of the specified Type.
Namespace: System
Assembly: mscorlib (in mscorlib.dll)
Parameters
- c
- Type: System.Type
The Type to compare with the current Type.
Return Value
Type: System.Booleantrue if c and the current Type represent the same type, or if the current Type is in the inheritance hierarchy of c, or if the current Type is an interface that c implements, or if c is a generic type parameter and the current Type represents one of the constraints of c. false if none of these conditions are true, or if c is null.
This method can be overridden by a derived class.
Note:
|
|---|
|
A generic type definition is not assignable from a closed constructed type. That is, you cannot assign the closed constructed type MyGenericList<int> (MyGenericList(Of Integer) in Visual Basic) to a variable of type MyGenericList<T>. |
You can determine the element types of a Type using GetElementType.
If the c parameter is of type TypeBuilder, the result is based on the type that is to be built. The following code example demonstrates this using a built type named B.
TypeBuilder b1 = moduleBuilder.DefineType("B", TypeAttributes.Public, typeof(A));
// Returns true:
typeof(A).IsAssignableFrom(b1))
The following example demonstrates the IsAssignableFrom method using defined classes, integer arrays, and generics.
Note:
|
|---|
|
To run this example, see Building Examples That Use a Demo Method and a TextBlock Control. |
using System; using System.Collections.Generic; class Example { public static void Demo(System.Windows.Controls.TextBlock outputBlock) { // Demonstrate classes: outputBlock.Text += "Defned Classes:" + "\n"; Room room1 = new Room(); Kitchen kitchen1 = new Kitchen(); Bedroom bedroom1 = new Bedroom(); Guestroom guestroom1 = new Guestroom(); MasterBedroom masterbedroom1 = new MasterBedroom(); Type room1Type = room1.GetType(); Type kitchen1Type = kitchen1.GetType(); Type bedroom1Type = bedroom1.GetType(); Type guestroom1Type = guestroom1.GetType(); Type masterbedroom1Type = masterbedroom1.GetType(); outputBlock.Text += String.Format("room assignable from kitchen: {0}\n", room1Type.IsAssignableFrom(kitchen1Type)); outputBlock.Text += String.Format("bedroom assignable from guestroom: {0}\n", bedroom1Type.IsAssignableFrom(guestroom1Type)); outputBlock.Text += String.Format("kitchen assignable from masterbedroom: {0}\n", kitchen1Type.IsAssignableFrom(masterbedroom1Type)); // Demonstrate arrays: outputBlock.Text += "\n"; outputBlock.Text += "Integer arrays:\n"; int[] array2 = new int[2]; int[] array10 = new int[10]; int[,] array22 = new int[2, 2]; int[,] array24 = new int[2, 4]; Type array2Type = array2.GetType(); Type array10Type = array10.GetType(); Type array22Type = array22.GetType(); Type array24Type = array24.GetType(); outputBlock.Text += String.Format("int[2] assignable from int[10]: {0}\n", array2Type.IsAssignableFrom(array10Type)); outputBlock.Text += String.Format("int[2] assignable from int[2,4]: {0}\n", array2Type.IsAssignableFrom(array24Type)); outputBlock.Text += String.Format("int[2,4] assignable from int[2,2]: {0}\n", array24Type.IsAssignableFrom(array22Type)); // Demonstrate generics: outputBlock.Text += "\n"; outputBlock.Text += "Generics:\n"; // Note that "int?[]" is the same as "Nullable<int>[]" int?[] arrayNull = new int?[10]; List<int> genIntList = new List<int>(); List<object> genObjList = new List<object>(); List<Exception> genExList = new List<Exception>(); Type arrayNullType = arrayNull.GetType(); Type genIntListType = genIntList.GetType(); Type genObjListType = genObjList.GetType(); Type genExListType = genExList.GetType(); outputBlock.Text += String.Format("int[10] assignable from int?[10]: {0}\n", array10Type.IsAssignableFrom(arrayNullType)); outputBlock.Text += String.Format("List<object> assignable from List<Exception>: {0}\n", genObjListType.IsAssignableFrom(genExListType)); outputBlock.Text += String.Format("List<object> assignable from List<int>: {0}\n", genObjListType.IsAssignableFrom(genIntListType)); } } class Room { } class Kitchen : Room { } class Bedroom : Room { } class Guestroom : Bedroom { } class MasterBedroom : Bedroom { } /* This code produces the following output: Defined Classes: room assignable from kitchen: true bedroom assignable from guestroom: true kitchen assignable from masterbedroom: false Integer arrays: int[2] assignable from int[10]: true int[2] assignable from int[2,4]: false int[2,4] assignable from int[2,2]: true Generics: int[10] assignable from int?[10]: false List<object> assignable from List<Exception>: false List<object> assignable from List<int>: false */
For a list of the operating systems and browsers that are supported by Silverlight, see Supported Operating Systems and Browsers.
The name of this method is vague and confusing when applied to testing inheritance or detecting interface implementations. The following wrapper for these purposes would make a lot more sense:
public static bool CanBeTreatedAsType(this Type CurrentType, Type TypeToCompareWith)
{
// Always return false if either Type is null
if (CurrentType == null || TypeToCompareWith == null)
return false;
// Return the result of the assignability test
return TypeToCompareWith.IsAssignableFrom(CurrentType);
}
Then, one can have more understandable application code such as:
bool CanBeTreatedAs = typeof(SimpleChildClass).CanBeTreatedAsType(typeof(SimpleClass));
CanBeTreatedAs = typeof(SimpleClass).CanBeTreatedAsType(typeof(IDisposable));
The advantage of this method instead of the 'is' keyword is that it can be used at run-time to test unknown, arbitrary Types, whereas the 'is' keyword (and a generic Type parameter) requires compile-time knowledge of specific Types.
- 10/26/2011
- wmarkjones
- 10/26/2011
- wmarkjones
Note: