Feedback

C# - Allgemeiner Invoke Aufruf für Property

Veröffentlicht von am 17.03.2017
(0 Bewertungen)
Sinn und Zweck

Die Klasse PropertyInvoke stellt verschiedene statische Funktionen bereit, mit denen sich ein Invoke für (nahezu) jedes Property schnell und einfach kodieren lässt. Dabei gibt es zwei Einschränkungen.

(1) Es hier nicht um die Laufzeit, dazu ist Code mit 'dynamic' Variablen einfach nicht geeignet.

(2) Es gibt Konstellationen in denen beide Varianten (Reflection wie unten, SetValue Methode) für ein 'Invoke' eines Property fehlschlagen; der Status 'InvokeRequired' wird dabei typischerweise niemals 'False', was zwangsläufig zu einem Stacküberlauf führt. Nach meinen Recherchen hat liegt dem ein Fehler in .Net zu Grunde. In diesen Fällen hilft nur ein Ausweichen auf den Aufruf einer klassichen Funktion, in welcher der 'Invoke' wiederum auf die Funktion (nicht auf das Property) führt.

Der Ansatz ist nicht wirklich neu, jedoch kombiniert er den eigentlichen Code zum 'Invoke' mit der Nutzung des Typs 'dynamic', was das Ganze recht flexibel anwendbar macht.

Allgemein

Letztlich läuft es auf ein 'Copy-and-Paste' hinaus, mit Anpassung des Property-Typen und -Namen.
Wichtig: in beiden Zweigen muss der Name des Propertys als String übergeben werden!

Anwendung mit dem Type 'dynamic'

public dynamic PropertyName {
get {
if (InvokeRequired)
return diub.Threads.PropertyInvoke.PropertyGetInvoke (this, "PropertyName");
//
// der eigentliche Property-Code
//
}
set {
if (InvokeRequired) {
diub.Threads.PropertyInvoke.PropertySetInvoke (this, "PropertyName", value);
return;
}
//
// der eigentliche Property-Code
//
}
}


Anwendung mit einem beliebigen Typ

Dafür benötigt man zusätzliche Delegaten für die get- und set-Funktionen.
delegate [PropertyType] Get[PropteryType]Delegate ();
delegate void Set[PropertyType]Delegate (PropertyType Obj);

public [PropertyType] PropertyName {
get {
if (InvokeRequired)
return diub.Threads.PropertyInvoke.PropertyGetInvoke<Get[PropertyType]Delegate> (this, "PropertyName");
//
// der eigentliche Property-Code
//
}
set {
if (InvokeRequired) {
diub.Threads.PropertyInvoke.PropertySetInvoke<Set[PropertyType]Delegate> (this, "PropertyName", value);
return;
}
//
// der eigentliche Property-Code
//
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;


namespace diub.Threads {

	public delegate dynamic GetValueDelegate ();
	public delegate void SetValueDelegate (dynamic obj);

	static public class PropertyInvoke {

		static public dynamic PropertyGetInvoke (this Control InvokeOnInstance, String PropertyName) {
			Delegate d;

			d = Delegate.CreateDelegate (typeof (GetValueDelegate), InvokeOnInstance, "get_" + PropertyName);
			return InvokeOnInstance.Invoke (d);
		}

		static public void PropertySetInvoke (this Control InvokeOnInstance, String PropertyName, dynamic Obj) {
			Delegate d;

			d = Delegate.CreateDelegate (typeof (SetValueDelegate), InvokeOnInstance, "set_" + PropertyName);
			InvokeOnInstance.Invoke (d, new object [] { Obj });
		}

		//

		static public T PropertyGetInvoke<T, D> (this Control InvokeOnInstance, String PropertyName) {
			Delegate d;

			d = Delegate.CreateDelegate (typeof (D), InvokeOnInstance, "get_" + PropertyName);
			return (T) InvokeOnInstance.Invoke (d);
		}

		//

		static public dynamic PropertyGetInvoke<D> (this Control InvokeOnInstance, String PropertyName) {
			Delegate d;

			d = Delegate.CreateDelegate (typeof (D), InvokeOnInstance, "get_" + PropertyName);
			return InvokeOnInstance.Invoke (d);
		}

		static public void PropertySetInvoke<D> (this Control InvokeOnInstance, String PropertyName, dynamic Obj) {
			Delegate d;

			d = Delegate.CreateDelegate (typeof (D), InvokeOnInstance, "set_" + PropertyName);
			InvokeOnInstance.Invoke (d, new object [] { Obj });
		}

	}   // class

}   // namespace	06.03.2017 - 20.05

Abgelegt unter Property, Invoke.

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!