#region Copyright 2009-2014 by Roger Knapp, Licensed under the Apache License, Version 2.0 /* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #endregion using System; using System.Collections.Generic; using System.Reflection; namespace CSharpTest.Net.Reflection { /// /// Allows reflection upon a property or field by name. /// public class PropertyType : ICustomAttributeProvider { private readonly Type _type; private readonly MemberInfo _member; /// /// Constructs the PropertyType info from a source type and an instance property or field name /// /// Any System.Type object to find the property or field on /// The name of the property or field to find public PropertyType(Type type, string name) { _type = Check.NotNull(type); Check.NotEmpty(name); BindingFlags baseFlags = BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy; //see if we can find a property by this name System.Type temp = _type; while (temp != typeof(Object) && _member == null) { _member = temp.GetProperty(name, baseFlags | BindingFlags.GetProperty | BindingFlags.SetProperty); if (_member == null) _member = temp.GetField(name, baseFlags | BindingFlags.GetField | BindingFlags.SetField); temp = temp.BaseType; } if (_member == null) throw new System.MissingMemberException(_type.FullName, name); } /// /// Walks a heirarchy of properties from the given type down. You can specify in any of the /// following ways: "ClientRectangle.X", "ClientRectangle/X" /// /// /// /// //dotted notation: /// PropertyType pt = PropertyType.TraverseProperties(typeof(Form), "ClientRectangle.X"); /// //path notation: /// PropertyType pt = PropertyType.TraverseProperties(typeof(Form), "ClientRectangle/X"); /// //individual names: /// PropertyType pt = PropertyType.TraverseProperties(typeof(Form), "ClientRectangle", "X"); /// /// /// Any System.Type object to traverse from /// The name of the properties or fields usually '.' delimited public static PropertyType TraverseProperties(Type fromType, params string[] propertyNames) { PropertyType prop = null; Type t = fromType; foreach (string propnames in Check.NotEmpty(propertyNames)) { foreach (string name in Check.NotEmpty(propnames).Split('.', '/', '\\')) { prop = new PropertyType(t, Check.NotEmpty(name)); t = prop.Type; } } return Check.NotNull(prop); } /// /// Returns the name of the property/field /// public string Name { get { return _member.Name; } } /// /// Returns the type of the property/field /// public Type Type { get { if (_member is PropertyInfo) return ((PropertyInfo)_member).PropertyType; else //if (_member is FieldInfo) return ((FieldInfo)_member).FieldType; } } /// /// Returns the value of the property for the specified instance /// public object GetValue(object instance) { if (_member is PropertyInfo) return ((PropertyInfo)_member).GetValue(instance, null); else //if (_member is FieldInfo) return ((FieldInfo)_member).GetValue(instance); } /// /// Sets the specified value for the instance supplied /// public void SetValue(object instance, object value) { if (_member is PropertyInfo) ((PropertyInfo)_member).SetValue(instance, value, null); else //if (_member is FieldInfo) ((FieldInfo)_member).SetValue(instance, value); } /// /// Returns an array of all of the custom attributes defined on this member, excluding named /// attributes, or an empty array if there are no custom attributes. /// public object[] GetCustomAttributes(bool inherit) { return _member.GetCustomAttributes(inherit); } /// /// Returns an array of custom attributes defined on this member, identified by type, or an /// empty array if there are no custom attributes of that type. /// public object[] GetCustomAttributes(Type attributeType, bool inherit) { return _member.GetCustomAttributes(attributeType, inherit); } /// /// Indicates whether one or more instance of is defined /// on this member. /// public bool IsDefined(Type attributeType, bool inherit) { return _member.IsDefined(attributeType, inherit); } } }