Sourcecode - PropertyDelegate

Download PropertyDelegate.cs

////////////////////////////////////////////////
////           PropertyDelegate             ////
////  Version 1.0.0               12.07.04  ////
////          www.danielgrunwald.de         ////
////////////////////////////////////////////////
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// 
using System;

namespace Grunwald.PropertyDelegates
{
	#region Base Class
	/// <summary>
	/// Abstract class for delegates pointing to properties.
	/// </summary>
	public abstract class PropertyDelegate
	{
		/// <summary>
		/// Creates a new PropertyDelegate pointing to the target property.
		/// </summary>
		protected PropertyDelegate(object target, string propertyName)
		{
			if (target == null) throw new ArgumentNullException("target");
			if (propertyName == null) throw new ArgumentNullException("propertyName");
			this.target = target;
			this.propertyName = propertyName;
			
			try {
				MakeGet();
				writeOnly = false;
			} catch (ArgumentException) {
				writeOnly = true;
			}
			try {
				MakeSet();
				readOnly = false;
			} catch {
				readOnly = true;
			}
			if (readOnly && writeOnly)
				throw new ArgumentException("Error binding to target property. Check" +
				                            "if the property exists and if the return "+
				                            "type is correct.");
		}
		
		bool readOnly, writeOnly;
		
		/// <summary>
		/// Is used internally to create the get-delegate.
		/// </summary>
		protected abstract void MakeGet();
		
		/// <summary>
		/// Is used internally to create the set-delegate.
		/// </summary>
		protected abstract void MakeSet();
		
		object target;
		string propertyName;
		
		/// <summary>
		/// Gets the target object.
		/// </summary>
		public object Target {
			get { return target; }
		}
		
		/// <summary>
		/// Gets the name of the property.
		/// </summary>
		public string PropertyName {
			get { return propertyName; }
		}
		
		/// <summary>
		/// Gets if the target property is read-only.
		/// </summary>
		public bool ReadOnly {
			get { return readOnly; }
		}
		
		/// <summary>
		/// Gets if the target property is write-only.
		/// </summary>
		public bool WriteOnly {
			get { return writeOnly; }
		}
	}
	#endregion
	
	#region String
	/// <summary>
	/// A delegate pointing to properties.
	/// </summary>
	public sealed class StringPropertyDelegate : PropertyDelegate
	{
		delegate string DelegateGet();
		delegate void DelegateSet(string value);
		
		DelegateGet getDelegate;
		DelegateSet setDelegate;
		
		/// <summary>
		/// Gets or sets the value of the target property.
		/// </summary>
		public string Value {
			get {
				if (WriteOnly) throw new InvalidOperationException("This delegate is write-only.");
				return getDelegate();
			}
			set {
				if (ReadOnly) throw new InvalidOperationException("This delegate is read-only.");
				setDelegate(value);
			}
		}
		
		/// <summary>
		/// Creates a new PropertyDelegate pointing to the specified property.
		/// </summary>
		public StringPropertyDelegate(object target, string propertyName)
		: base(target, propertyName)
		{
		}
		
		/// <summary>
		/// Is used internally to create the get-delegate.
		/// </summary>
		protected override void MakeGet() {
			getDelegate = (DelegateGet)Delegate.CreateDelegate(typeof(DelegateGet), Target, "get_" + PropertyName);
		}
		
		/// <summary>
		/// Is used internally to create the set-delegate.
		/// </summary>
		protected override void MakeSet() {
			setDelegate = (DelegateSet)Delegate.CreateDelegate(typeof(DelegateSet), Target, "set_" + PropertyName);
		}
	}
	#endregion
	
	// continue this for every type you need...
	// or use generics if you have .NET 2.0!
}