CSharp examples for System.Reflection:Type
if a type is anonymous based on the language spec.
using System.Threading.Tasks; using System.Text; using System.Runtime.Serialization; using System.Runtime.CompilerServices; using System.Reflection.Emit; using System.Reflection; using System.Linq; using System.IO;// w w w . j av a 2s . c o m using System.Globalization; using System.Collections.Generic; using System; public class Main{ /// <summary> /// HACK: This is a best effort attempt to divine if a type is anonymous based on the language spec. /// /// Reference section 7.6.10.6 of the C# language spec as of 2012/11/19 /// /// It checks: /// - is a class /// - descends directly from object /// - has [CompilerGenerated] /// - has a single constructor /// - that constructor takes exactly the same parameters as its public properties /// - all public properties are not writable /// - has a private field for every public property /// - overrides Equals(object) /// - overrides GetHashCode() /// </summary> public static bool IsAnonymouseClass(this Type type) // don't fix the typo, it's fitting. { if (type.IsValueType()) return false; if (type.BaseType() != typeof(object)) return false; var compilerGenerated = type.GetTypeInfo().CustomAttributes.Any(a => a.AttributeType == typeof(CompilerGeneratedAttribute)); if (!compilerGenerated) return false; var allCons = type.GetConstructors(); if (allCons.Length != 1) return false; var cons = allCons[0]; if (!cons.IsPublic) return false; var props = type.GetProperties(); if (props.Any(p => p.CanWrite)) return false; var propTypes = props.Select(t => t.PropertyType).ToList(); foreach (var param in cons.GetParameters()) { if (!propTypes.Contains(param.ParameterType)) return false; propTypes.Remove(param.ParameterType); } if (propTypes.Count != 0) return false; var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic); if (fields.Any(f => !f.IsPrivate)) return false; propTypes = props.Select(t => t.PropertyType).ToList(); foreach (var field in fields) { if (!propTypes.Contains(field.FieldType)) return false; propTypes.Remove(field.FieldType); } if (propTypes.Count != 0) return false; var equals = type.GetMethod("Equals", new Type[] { typeof(object) }); var hashCode = type.GetMethod("GetHashCode", new Type[0]); if (!equals.IsOverride() || !hashCode.IsOverride()) return false; return true; } public static bool IsOverride(this MethodInfo method) { return method.GetBaseDefinition() != method; } public static bool IsPublic(this Type type) { var info = type.GetTypeInfo(); return info.IsPublic; } public static bool IsValueType(this Type type) { var info = type.GetTypeInfo(); return info.IsValueType; } public static Type BaseType(this Type type) { var info = type.GetTypeInfo(); return info.BaseType; } public static MethodInfo GetMethod(this Type type, string name, BindingFlags flags, Type[] parameterTypes) { var info = type.GetTypeInfo(); var mtds = info.GetMethods(flags).Where(m => m.Name == name); foreach (var mtd in mtds) { var ps = mtd.GetParameters(); if (ps.Length != parameterTypes.Length) continue; var allMatch = true; for (var i = 0; i < ps.Length; i++) { var p = ps[i].ParameterType; var pt = parameterTypes[i]; if (p != pt) { allMatch = false; } } if (allMatch) { return mtd; } } return null; } }