static Type GetPublicRuntimeType(Type symType)
{
if (symType == null)
{
return symType;
}
// Find try to find a public class-type
Type pubType = symType;
while ((pubType != null) && (!pubType.IsPublic) && (!pubType.IsNestedPublic))
{
pubType = pubType.BaseType;
}
bool isObject = (pubType == typeof(object));
if (isObject)
{
// Rather try to find a more specific interface-type
// instead, although we remember that this is an object and
// revert back to that type if no public interface is found
pubType = null;
}
if (pubType == null)
{
// As a last resort, try to find a public interface-type
System.Collections.Generic.List<Type> interfaceTypes =
new System.Collections.Generic.List<Type>();
int interfaceIndex = 0;
while ((pubType == null) &&
(symType != null) &&
(symType != typeof(object)))
{
foreach (Type interfaceType in symType.GetInterfaces())
{
if (interfaceTypes.Contains(interfaceType))
{
continue;
}
interfaceTypes.Add(interfaceType);
}
symType = symType.BaseType;
while (interfaceIndex < interfaceTypes.Count)
{
Type interfaceType = interfaceTypes[interfaceIndex++];
if (interfaceType.IsPublic || interfaceType.IsNestedPublic)
{
pubType = interfaceType;
break;
}
interfaceType = interfaceType.BaseType;
if ((interfaceType == null) ||
(interfaceType == typeof(object)) ||
(interfaceTypes.Contains(interfaceType)))
{
continue;
}
interfaceTypes.Add(interfaceType);
}
}
}
return pubType ?? ((isObject) ? typeof(object) : null);
}