Laden...

Event aus einer Methode ausführen

Erstellt von c#-forscher vor 13 Jahren Letzter Beitrag vor 13 Jahren 832 Views
C
c#-forscher Themenstarter:in
4 Beiträge seit 2010
vor 13 Jahren
Event aus einer Methode ausführen

Hallo, ich hoffe jemand kann mir weiterhelfen.
Ich habe ein Problem damit ein Event aus einer normalen Methode auszuführen.
Event aus der Eigenschaftsmethode funktioniert reibungslos.

Code:

 
using System;
using System.Collections;

namespace simpleEvent
{
	public delegate void InvalidRadiusEventHandler(Circle c, InvalidRadiusEventArgs e);
	
	public class InvalidRadiusEventArgs : EventArgs
	{
		private double _Radius;
		public InvalidRadiusEventArgs(double radius)
		{
			_Radius = radius;
		}
//Dem Ereignishaendler wird der Wert des fehlgeschlagenen Zuweisungsversuchs mitgeteilt.	
		public double Radius
		{
			get { return _Radius; }
		}
	}
	
	public class Circle
	{
		public event InvalidRadiusEventHandler InvalidRadius;
		
		private double _Radius;
		public virtual double Radius
		{
			get{return _Radius;}
			set
			{
				if(value >= 0)
				  _Radius = value;
				else if

				  (InvalidRadius != null)

			/*funkioniert einwandfrei*/[CSHARP]  InvalidRadius(this, new InvalidRadiusEventArgs(value));
			}
		}
		//Konstruktoren
        public Circle()
        {
			Console.WriteLine("Der parameterlose Konstrukter wird aussgeführt.");
        }

        public Circle(double r) : this()
			_Radius = r;
			OnInvalidRadius();
			Console.WriteLine("Der parametrisierte Konstruktor wird ausgeführt");
        }
		public void OnInvalidRadius()
		{
			if (_Radius >= 0)
               this.Radius = _Radius;
		    else if
				(InvalidRadius != null)
		/*Da ist das Problem!*/InvalidRadius(this, new InvalidRadiusEventArgs(_Radius));
			Console.WriteLine("Die OnInvalidRadius-Methode wird ausgefuehrt.");
			Console.WriteLine("Der Radius in der Methode ist {0} cm gross", this.Radius);
		}
	}
	
	class MainClass
	{		
		public static void Main (string[] args)
		{			
			Console.Clear();
			Circle kreis = new Circle(-8008);
			kreis.InvalidRadius += new InvalidRadiusEventHandler(kreis_InvalidRadius);
			Console.Write("Geben Sie bitte den Radius fuer den Circle ein: ");
			kreis.Radius = Convert.ToDouble(Console.ReadLine());
		}
//Das Delegate aktiviert folgende Methode (Ereignishandler)
		
		public static void kreis_InvalidRadius(Circle sender, InvalidRadiusEventArgs e)
		{
			
			Console.WriteLine("Unzulaessiger negativer Radius");
			Console.WriteLine("Der Radius von {0} ist nicht zulaessig.", e.Radius);
			Console.Write("Neueingabe: ");
/* Dem Radius kann ein neuer Wert zugewiesen werden, der sofort 
 * an die Eignschaftsmethode weitergeleitet wird. */
			sender.Radius = Convert.ToDouble(Console.ReadLine());
			Console.WriteLine("Neuer Radius betraegt: {0} cm", sender.Radius);
		}
	}
}

F
155 Beiträge seit 2009
vor 13 Jahren

Hallo,

der Aufruf funktioniert schon, nur wird das Event erst nach dem Aufruf registriert, somit ist InvalidRadius beim Aufruf null und es passiert nichts.


 if (InvalidRadius != null)
       InvalidRadius(this, new InvalidRadiusEventArgs(_Radius));


 public virtual double Radius
        {
            get{return _Radius;}
            set
            {
                if(value >= 0)
                  _Radius = value;
                else 
                    OnInvalidRadius();
            }
        }

so ist es besser.

fz

"We better hurry up and start coding, there are going to be a lot of bugs to fix."

1.552 Beiträge seit 2010
vor 13 Jahren

Hallo F.Z.

so ist es zwar besser, aber fehlerhaft, denn InvalidRadius ist null, wie du selbst sagtest. Durch deinen Code wird die null überprüfung getilgt, was aber fatal ist.
Sein Problem ist dass er den Radius im Konstruktor setzt und erst danach das Event zuweist.

Ich mach das immer so, dass bei gewissen Methoden dort wo korrekte Parameter gefordert sind, diese immer geprüft werden. Also in deinem Fall:


public Circle(double r) 
{
    if(r <= 0)
        throw new OutOfBoundariesException("value should be greather 0");
    _Radius = r;
}

Und deine OnInvalidRadius() macht nicht das was sie sagt das sie macht. Sie sagt dass sie nur aufgerufen werden möchte wenn der Radius ungültig ist und nicht dass sie intern noch die Prüfung macht ob der Radius nun gültig wäre.

Gruß
Michael

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

F
155 Beiträge seit 2009
vor 13 Jahren

Hallo,


 public void OnInvalidRadius()
        {
            if (_Radius >= 0)
               this.Radius = _Radius;
            else if
                (InvalidRadius != null) //hier wird ja überprüft
        InvalidRadius(this, new InvalidRadiusEventArgs(_Radius));
            Console.WriteLine("Die OnInvalidRadius-Methode wird ausgefuehrt.");
            Console.WriteLine("Der Radius in der Methode ist {0} cm gross", this.Radius);
        }

fz

"We better hurry up and start coding, there are going to be a lot of bugs to fix."

1.552 Beiträge seit 2010
vor 13 Jahren

Ups F.Z.

irgenwie habe ich zwischen deinen Zeilen gelesen dass du die null Überprüfung entfernen willst 😁

Das Problem am anfänglichem Beispiel ist ja dass der User der Klasse nicht eine Meldung bekommt wenn das Event nicht registriert ist. Die einzige Möglichkeit im Beispiel wäre den Standardkonstruktor aufzurufen, dann das Event zu registrieren und erst dann den Radius zu setzten, oder er verwendet meine Vorgeschlagene Methode, die auch im .NET häufig verwendet wird.

Note: Die Konstruktorverkettung in diesem Beispiel aufgrund dessen dass der Standardkonstruktor nichts macht sinnlos.

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

C
c#-forscher Themenstarter:in
4 Beiträge seit 2010
vor 13 Jahren

Vielen Dank euch beiden.