How do I determine if a property is a user-defined type? I tried to use IsClass as shown below but its value was true for String properties (and who knows what else).
foreach (var property in type.GetProperties()) {
if (property.PropertyType.IsClass) {
// do something with property
}
}
* Updated for more clarity *
I am trying to traverse a given type's definition and if the given type or any of its public properties are defined within the assembly, I am searching for an embedded JavaScript document. I just don't want to waste processing resources and time on native .NET types.
If by "user-defined" you mean that it is not part of the standard assembly (mscorlib) then you can do something along the lines of this:
if(typeof(SomeType).Assembly.GetName().Name != "mscorlib") {
// user-defined!
}
However this will also consider types from external assemblies (aka: libraries) to be considered "user-defined". If you only want those in your current assembly then you can use
typeof(SomeType).Assembly == Assembly.GetExecutingAssembly()
@Bobson made a really good point:
"...Unlike some other languages, C# does not make any actual
distinction between "user-defined" and "standard" types."
Technically, @Bobson gave the answer; there is no distinguishing difference between a user-defined type and one defined in the .NET Framework or any other assembly for that matter.
However, I found a couple useful ways to determine if a type is user-defined.
To search for all types defined within the given type's assembly, this works great:
foreach (var property in type.GetProperties()) {
if (property.PropertyType.IsClass
&& property.PropertyType.Assembly.FullName == type.Assembly.FullName) {
// do something with property
}
}
If the types can be defined in various assemblies, excluding the System namespace works in most cases:
foreach (var property in type.GetProperties()) {
if (property.PropertyType.IsClass
&& !property.PropertyType.FullName.StartsWith("System.")) {
// do something with property
}
}
I wrote a generic populator for unit testing that assigns predictable values to my objects and came across this kind of problem. In my case I wanted to know which of my properties were objects so that I could recursively populate those object properties, again with predictable values.
It seemed to me that introducing an interface implemented only by the classes that I was interested in traversing was the best way to do this. You can then test to see if your property is an object of interest:
public static bool IsMyInterface(this Type propertyType)
{
return propertyType.GetInterface("MyInterfaceName") != null;
}
If by "user-defined" type you mean type that was declared in your executing assembly then you can obtain list of that types like in this sample c# console application:
class Program
{
static void Main( string[] args )
{
var currentAssembly = Assembly.GetExecutingAssembly();
var localTypes = currentAssembly.GetTypes();
}
}
UPDATE:
If you want to obtain list of types from all referenced assemblies:
class Program
{
static void Main( string[] args )
{
var currentAssembly = Assembly.GetExecutingAssembly();
var referencedAssemblies = currentAssembly.GetReferencedAssemblies();
var typesFromReferencedAssemblies = referencedAssemblies.Select( assemblyName => Assembly.ReflectionOnlyLoad( assemblyName.FullName ) ).SelectMany( assembly => assembly.GetTypes() );
}
}
Just be aware that Program
type will also be in that list. Is this sufficient answer to your problem?
Say your project is named "Foobar" and everything you make is under that namespace. You can test to see if you've written it by the following method:
typeof(SomeType).Namespace.Contains("Foobar");