Discovering Derived Types Using Reflection

Discovering derived types using reflection

pretty much the same as Darin's but here you go..

    public static List<Type> FindAllDerivedTypes<T>()
{
return FindAllDerivedTypes<T>(Assembly.GetAssembly(typeof(T)));
}

public static List<Type> FindAllDerivedTypes<T>(Assembly assembly)
{
var baseType = typeof(T);
return assembly
.GetTypes()
.Where(t =>
t != baseType &&
derivedType.IsAssignableFrom(t)
).ToList();

}

used like:

var output = FindAllDerivedTypes<System.IO.Stream>();
foreach (var type in output)
{
Console.WriteLine(type.Name);
}

outputs:

NullStream
SyncStream
__ConsoleStream
BufferedStream
FileStream
MemoryStream
UnmanagedMemoryStream
PinnedBufferMemoryStream
UnmanagedMemoryStreamWrapper
IsolatedStorageFileStream
CryptoStream
TailStream

Using reflection with derived objects

I am not sure what you are trying to accomplish and if it is the best way to do it. But I have changed the code so it works. I have not made it as dynamic as it can be...

public class Base
{
public Prop prop { get; set; }
}

public class Derived : Base
{

// some other properties of the derived class , not so relevant....
}

public class Prop
{

public String propString { get; set; }
}
public class MyClass
{
public void SecondFunc(object obj)
{
Type type = obj.GetType();
var allClassProperties = type.GetProperties();
foreach (var propertyInfo in allClassProperties)
{
if (propertyInfo.PropertyType == typeof(Prop))
{
var pVal = (Prop)propertyInfo.GetValue(obj, null);
if(pVal == null)
{
//creating a new instance as the instance is not created in the ctor by default
pVal = new Prop();
propertyInfo.SetValue(obj, pVal, null);
}
this.SecondFunc(pVal);
}
else if (propertyInfo.PropertyType == typeof(string))
{
string value = (string)propertyInfo.GetValue(obj, null);
string afterRemovalValue = myManipulationStringFunc(value);

propertyInfo.SetValue(obj, afterRemovalValue, null);
}
}
}

private string myManipulationStringFunc(string value)
{
if (string.IsNullOrEmpty(value))
value = "Value was NULL";
return value;
}
}

I hope this helps...

How to identify derived classes that is going to affect when base class is modified

In Visual Studio you would right click on the thing you want to change and in the popup menu select either View all references or View call hierarchy.

If you want to do it yourself in code you would use reflection for example as described in Discovering derived types using reflection.

Enumerating derived types

The first step is to get a Type object for each of your derived types. Pavel's answer gives you a good base for that, though his solution only gives direct subtypes, not types further down the inheritance chain, and only types defined in the same assembly as the base type. Here's a slightly updated version:

var baseType = typeof(Base);
var currentlyLoadedAssemblies = AppDomain.Current.GetAssemblies();
var relevantTypes = currentlyLoadedAssemblies
.SelectMany (assembly => assembly.GetTypes())
.Where(type => baseType.IsAssignableFrom(type));
Types = relevantTypes.ToList();

No we have all the types, we can bind them to a WPF combobox. Rather than extracting the strings from the type names, we'll bind to the Type object itself, so when the user selects one, we'll have the selected Type object ready. We'll tell the ComboBox to display the Type's Name property.

public List<Type> Types {get;set;}
public Type SelectedType {get;set;}

<ComboBox ItemsSource="{Binding Types}"
SelectedItem="{Binding SelectedType}"
DisplayMemberPath="Name" />

How to find all the types in an Assembly that Inherit from a Specific Type C#

Something like:

public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
return assembly.GetTypes().Where(t => baseType.IsAssignableFrom(t));
}

If you need to handle generics, that gets somewhat trickier (e.g. passing in the open List<> type but expecting to get back a type which derived from List<int>). Otherwise it's simple though :)

If you want to exclude the type itself, you can do so easily enough:

public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
return assembly.GetTypes().Where(t => t != baseType &&
baseType.IsAssignableFrom(t));
}

Note that this will also allow you to specify an interface and find all the types which implement it, rather than just working with classes as Type.IsSubclassOf does.

Get all c# Types that implements an interface first but no derived classes

Firstly, I'd use Type.IsAssignableFrom rather than GetInterfaces, but then all you need to do is exclude types whose parent type is already in the set:

var allClasses = types.Where(type => typeof(IFace).IsAssignableFrom(type))
.ToList(); // Or use a HashSet, for better Contains perf.
var firstImplementations = allClasses
.Except(allClasses.Where(t => allClasses.Contains(t.BaseType)));

Or as noted in comments, equivalently:

var firstImplementations = allClasses.Where(t => !allClasses.Contains(t.BaseType));

Note that this will not return a class which derives from a class which implements an interface, but reimplements it.

Use reflection to get instances of static instances of derived class

It's important to understand that it's the field which is static - not the instance.

You can easily find readonly static fields though, and fetch their values. For example:

var someAssembly = typeof(Foo).Assembly; // Or whatever
var values = from type in someAssembly.GetTypes()
from field in type.GetFields(BindingFlags.Static |
BindingFlags.Public |
BindingFlags.NonPublic)
where field.IsInitOnly &&
field.FieldType == typeof(LocalisationToken)
select (LocalisationToken) field.GetValue(null);

Reflection : Getting members from inherited interface, but not from inherited class

You can go about this in a number of ways, depending on your exact aim.

One idea is to get all properties normally then filter out those coming from class A using DeclaringType, e.g.

var typeOfA = typeof(A);
var notFromA = allMembers.Where(
p => p.DeclaringType != typeOfA && !p.DeclaringType.IsSubclassOf(typeOfA));

Or of course you can simply ignore the base class completely and get only the members coming from implemented interfaces, e.g.

var members = typeof(B).GetInterfaces().SelectMany(i => i.GetMembers());

This will give you all members of B that are implementations of interface members -- not necessarily all of B's declared members, and it will include interface members that A has implemented.

In general the correct way to do this depends on the exact requirements, but I feel the question is not precise enough in its current form.



Related Topics



Leave a reply



Submit