Laden...

Forenbeiträge von AtzeX Ingesamt 217 Beiträge

28.05.2007 - 12:58 Uhr

Hi VizOne,

danke dir für die Info/Idee.
Dieser Code funktioniert nun:

    class ThreadSafeList<T> : IEnumerable<T>
    {
        private ReaderWriterLock rwl = new ReaderWriterLock();
        private List<T> list = new List<T>();

        public void Add(T item)
        {
            //Acquire a write lock on the resource.
            rwl.AcquireWriterLock(Timeout.Infinite);
            try
            {
                list.Add(item);
            }
            finally
            {
                rwl.ReleaseWriterLock();
            }
        }

        #region IEnumerable<T> Members
        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            //Acquire a read lock on the resource.
            rwl.AcquireReaderLock(Timeout.Infinite);
            try
            {
                foreach (T item in this.list)
                {
                    yield return item;
                }
            }
            finally
            {
                rwl.ReleaseReaderLock();
            }
        }
        #endregion

        #region IEnumerable Members
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            foreach (T item in this.list)
            {
                yield return item;
            }
        }
        #endregion
    }

Aber einfacher bzw. ohne Wrapper geht das gar nicht, oder?

Edit:
Wo ich gerade noch einmal dies hier lese:

Du solltest also einen eigenen Enumerator schreiben, dessen Dispose() Methode erst ReleaseReaderLock aufruft. Du meintest das anders, als ich es nun gelöst habe, richtig?
Hast du evtl. ein Beispiel, ich kann nicht ganz folgen.

28.05.2007 - 11:43 Uhr

Hallo.

Ich wollte den heutigen Feiertag nutzen, um ein Problem anzugehen, welches ich schon länger auf der Liste habe.

In einer Klasse habe ich eine Generic List als Member definiert.
Die Klasse 'füllt' die List selber mit Strings.
Mittels einer public Property exportiere ich diese List.

Wenn nun Code eines anderen Threads diese Property verwendet, um die zurückgegebene List mittels ForEach zu iterieren, so wird ab und an die Exception "System.InvalidOperationException" (Die Auflistung wurde geändert. Der Enumerationsvorgang kann möglicherweise nicht ausgeführt werden.) geworfen.
Den Grund dafür kenne ich: Die Generic List ist nicht Threadsafe.

Also wollte ich mir eine threadsichere Ableitung von List erstellen.
Da die Members von List aber nicht überschreibbar sind, habe ich das gelassen.

Also habe ich mir eine Art Wrapper erstellt.
Dieser ist hier einmal abgebildet.
Ich könnte schwören, dass es schon funktionierte, nur nun auf einmal nicht mehr, die gleiche oben genannte Exception wird geworfen.
Meine erste Frage wäre warum das nicht funktioniert.

class ThreadSafeList<T> : IEnumerable<T>
    {
        private ReaderWriterLock rwl = new ReaderWriterLock();
        private List<T> list = new List<T>();

        public void Add(T item)
        {
            //Acquire a write lock on the resource.
            rwl.AcquireWriterLock(Timeout.Infinite);
            try
            {
                list.Add(item);
            }
            finally
            {
                rwl.ReleaseWriterLock();
            }
        }

        #region IEnumerable<T> Members
        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            //Acquire a read lock on the resource.
            rwl.AcquireReaderLock(Timeout.Infinite);
            try
            {
                return ((IEnumerable<T>)this.list).GetEnumerator();
            }
            finally
            {
                rwl.ReleaseReaderLock();
            }
        }
        #endregion

        #region IEnumerable Members
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            throw new Exception("The method or operation is not implemented.");
        }
        #endregion

Testen tue ich den Code z.B. hiermit:

class Program
    {
        static ThreadSafeList<string> tsl = new ThreadSafeList<string>();

        static void Main(string[] args)
        {
            System.Threading.Thread thread = new System.Threading.Thread(PrintList);
            thread.IsBackground = true;
            thread.Start();

            for (int i = 0; i < 100000; i++)
            {
                tsl.Add(i.ToString());
            }

            Console.ReadKey();
        }

        static void PrintList()
        {
            for (int i = 0; i < 100; i++)
            {
                foreach (string s in tsl)
                {
                    Console.WriteLine(s);
                }
            }
        }
    }

Meine zweite Frage ist, ob es vielleicht eine andere Möglichkeit gibt, die Generic List autag (als echte Kopie?) zu exportieren?

Vielleicht mache ich alles auch viel zu kompliziert?

Vielen Dank im Vorraus,
AtzeX

02.05.2007 - 21:21 Uhr

Original von herbivore

Und du bist der Meinung, dass so eine Parameterbündelung, auch wenn sie praktikabel ist, nicht verwendet werden sollte, da sie in der Realität keine Entsprechung hat?
Ja!

herbivore

Hallo herbivore,

noch einmal zu zitiertem Sachverhalt von oben. 😉
Wie siehst du deine Aussage in Bezug auf ein "ProcessStartInfo"?
Das ist doch auch ein eher nicht-reeller Typ, der aber Sinn macht.

So könnte ich meine 'Parameterbündelung' ja auch z.B. "MyObjectInitInfo" nennen, oder?

Trennst du das wirklich so stringent?

Nicht, dass es schlimm ist mit deiner Aussage zu leben, mir kam nur gerade das "ProcessStartInfo" in die Quere und ich fühlte mich prompt erinnert.

Gruß,
Atze

30.04.2007 - 13:06 Uhr

@Parsifal:
Das ist eine 3rd Party Komponente von einem unserer Partner.

@Herbivore:
Ja, diese Komponente ist ein essentieller Bestandteil der Gesamtlösung.
Sie ist quasi der Zugang (oder sollte ich sagen das 'Interface' 😉 ) zu einem System, für das mein Programm erstellt wird.

Es scheint wohl darauf hinauszulaufen.

30.04.2007 - 11:16 Uhr

Ok, vielleicht fange ich es einmal anders an.

Ich muss eine externe Komponente verwenden, diese deshalb entsprechend referenzieren.
Nennen wir diese einmal "EK.DLL".
Darin sind Typen, die ich verwenden muss.
Nehmen wir als Beispiel einmal "EkTyp1" und "EkTyp2".

Nun habe ich in meinem Programm einen "TypMain" und einen "TypSub".
Beide referenzieren "EK.DLL", da beide Teile davon verwenden.
"TypMain" referenziert "TypSub", instanziiert ein Feld von seinem Typ und arbeitet damit.

Nehmen wir an, ich möchte noch weitere "TypSubs" erstellen und die Anwendung PlugIn-Fähig machen.
Also soll jedes "TypSub" eine eigene Assembly werden. Die "TypSub" müssen natürlich weiterhin die "EK.DLL" referenzieren.

Jedoch sollen nun sowohl "TypMain", als auch die "TypSubs" eine von mir nun noch zu erstellende Interface-dll referenzieren um das Interface verwenden/implementieren zu können.

Und genau da ist der Hund begraben.
In diesem Interface-Assembly müsste ich auch die "EK.DLL" referenzieren, da ich Typen (z.B. "EkTyp1" und "EkTyp2") der "EK.DLL" im Interface anwenden muss, da sowohl die "TypSubs" also auch "TypMain" damit arbeiten.
Das heißt, dass das Interface mit der externen Komponente verwoben ist.

Irgendwie bleibt mir aber scheinbar nichts anderes übrig, oder?

Oder ist meine Denkweise falsch?

P.S.:
Ich merke schon, wie schwer es mir fällt das zu formulieren. Vielleicht ist es ja wirklich ein 'Kopfproblem'?

Gruß,
Atze

29.04.2007 - 23:06 Uhr

Ich glaube wir reden an einander vorbei.
Ich meine den ersten Teile meines Postings:

Ich arbeite gerade an einem Projekt, dessen essentieller Bestandteil eine externe Bibliothek (DLL) ist, die ich einbinden muss.
In dieser Bibliothek werden natürlich auch Typen definiert, die ich umfassend verwende.

Mein Programm besteht auch aus mehreren selbsterstellten Komponenten, die ich nun mittels Interfaces entkoppeln möchte.

Ich habe mir nun Gedanken gemacht, wie meine Schnittstelle aussehen soll.
Es stellt sich nun so dar, dass ich dort Typen verwenden muss, die in der externen Bibliothek definiert sind, da ich diese Typen überall in meinem Programm verwende.
Meine Schnittstellen wollte ich in eine eigenständige Assembly packen.
Das hat zur Folge, dass ich in diesem Klassenbibliothekenprojekt auch auf die externe Bibliothek verweisen muss, damit ich die dort definierten Typen verwenden kann.

Das gefällt mir aber nicht so sehr, da sich an dieser Bibliothek ja auch schon mal was ändert, was zur Folge hat, dass ich meine Interface-Dll neu erstellen muss, obwohl sich an meinem Interface selber evtl. gar nichts geändert hat. Dies zieht natürlich auch wieder einen Rattenschwanz nach sich.

Ich habe auch schon überlegt, eine Art Wrapper für die externe Bibliothek zu erstellen, doch die benötigten Typen/Funktionalitäten sind wirklich umfangreich.

Hat jemand evtl. einen besseren Ansatz, wie ich das praktikabel umsetzen kann?

Und du sicher den Zweiten, richtig?

Noch eine andere Frage zum Thema Interface-Klassenbibliotheken.
Ist es ok, dort einfache Strukturen/Klassen zu definieren?
Ich habe z.B. recht einfache Strukturen, um Methodenparameter zu 'bündeln'.
Statt (übertrieben) 10 einzelne Parameter zu übergeben, übergebe ich lieber einen vom Typ meiner Struktur/Klasse, welche zuvor entsprechend initialisiert wurde.
Das hilft mir Übersicht zu schaffen.
Da macht es doch Sinn, diesen mit in die DLL zu packen, oder?

29.04.2007 - 22:42 Uhr

Ok, jetzt habe ich dich.
Aber diese Interfaces würden z.B. Typen der externen Komponente als Parameter enthalten...

29.04.2007 - 22:26 Uhr

Ich kann das leider nicht ganz zuordnen.
Meinst du meine Interfaces?

29.04.2007 - 20:30 Uhr

Hi Herbivore,
was bitte meinst du mit

sondern darfst nur die Interfaces nehmen. ?

Und du bist der Meinung, dass so eine Parameterbündelung, auch wenn sie praktikabel ist, nicht verwendet werden sollte, da sie in der Realität keine Entsprechung hat?

29.04.2007 - 19:49 Uhr

Ich arbeite gerade an einem Projekt, dessen essentieller Bestandteil eine externe Bibliothek (DLL) ist, die ich einbinden muss.
In dieser Bibliothek werden natürlich auch Typen definiert, die ich umfassend verwende.

Mein Programm besteht auch aus mehreren selbsterstellten Komponenten, die ich nun mittels Interfaces entkoppeln möchte.

Ich habe mir nun Gedanken gemacht, wie meine Schnittstelle aussehen soll.
Es stellt sich nun so dar, dass ich dort Typen verwenden muss, die in der externen Bibliothek definiert sind, da ich diese Typen überall in meinem Programm verwende.
Meine Schnittstellen wollte ich in eine eigenständige Assembly packen.
Das hat zur Folge, dass ich in diesem Klassenbibliothekenprojekt auch auf die externe Bibliothek verweisen muss, damit ich die dort definierten Typen verwenden kann.

Das gefällt mir aber nicht so sehr, da sich an dieser Bibliothek ja auch schon mal was ändert, was zur Folge hat, dass ich meine Interface-Dll neu erstellen muss, obwohl sich an meinem Interface selber evtl. gar nichts geändert hat. Dies zieht natürlich auch wieder einen Rattenschwanz nach sich.

Ich habe auch schon überlegt, eine Art Wrapper für die externe Bibliothek zu erstellen, doch die benötigten Typen/Funktionalitäten sind wirklich umfangreich.

Hat jemand evtl. einen besseren Ansatz, wie ich das praktikabel umsetzen kann?

Noch eine andere Frage zum Thema Interface-Klassenbibliotheken.
Ist es ok, dort einfache Strukturen/Klassen zu definieren?
Ich habe z.B. recht einfache Strukturen, um Methodenparameter zu 'bündeln'.
Statt (übertrieben) 10 einzelne Parameter zu übergeben, übergebe ich lieber einen vom Typ meiner Struktur/Klasse, welche zuvor entsprechend initialisiert wurde.
Das hilft mir Übersicht zu schaffen.
Da macht es doch Sinn, diesen mit in die DLL zu packen, oder?

Gruß,
Atze

27.04.2007 - 21:24 Uhr

Hallo,

sorry, dass ich mich nun erst melde, aber ich war leider verhindert.

Der Thread hat sich ja gut entwickelt.
Danke an alle Beteiligten!

Gruß,
AtzeX

22.04.2007 - 22:35 Uhr

Hallo zusammen.

Ich war gerade in Laune und wollte mir schnell noch einmal klar machen, was es alles für Vorteile mit sich bringt, gegen Interfaces zu programmieren.

Gar nicht mal so einfach, da eine Zusammenfassung zu bekommen.
Weder in deutsch noch in englisch finde ich einen Artikel, der es mal auf den Punkt bringt.
Wäre es nicht Zeit für einen entsprechenden Artikel hier im Forum, zumal das ein immer wiederkehrendes Thema ist und der ein oder andere hier an Board auch den Satz "Programmiere immer gegen Interfaces" predigt?

Also nicht das WIE ist interessant, sondern das WARUM.
Damit man das mal wirklich verinnerlicht.

Ich muss leider immer mal wieder etwas nachlesen, weil mir alles mögliche im Kopf rumschwirrt, und dann habe ich mal wieder etwas vergessen und und und...

Deshalb mal meine Frage:

Warum sollte man immer gegen Interfaces programmieren?

Danke euch!

14.04.2007 - 11:04 Uhr

Hi axelfxxx,

das hier ist wohl die passende Anlaufstelle dafür:
http://www.pinvoke.net

Gruß,
AtzeX

11.04.2007 - 11:16 Uhr

So stellt es sich in der Tat dar. Leider.

Na ja, ich dachte halt, weil es bei der eigentlichen Ausführung von PKUNZIP.EXE in der Kommandozeile ja auch schon zu lesen ist, bevor es abgebrochen wird, dass es ginge.

11.04.2007 - 08:21 Uhr

Nochmal zu meiner Kernfrage:

Egal was ich probiere, ich bekomme keine Infos aus StdOut wenn das Programm hängt und ich es selber beenden muss.

Kann es sein, dass das ein Ding der Unmöglichkeit ist?
Wenn ich z.B. PKUNZIP.EXE aus der Kommandozeile heraus aufrufe und StdOut in eine Datei umleiten lassen möchte, klappt das wenn ich das Programm 'normal', also mit Tastendruck beende.

Wenn ich es jedoch abbreche, dann ist die erstellte Datei leer.

Verwendete Commandline:

PkUnzip.exe > output.txt

Das wäre ja wirklich mies.

10.04.2007 - 19:04 Uhr

Hallo.

Ich komme einfach nicht weiter. Ich möchte gerne die StdOut eines selber gestarteten Prozesses auslesen.
Diese benötige ich aber auch, wenn das (in meinem Fall ein Konsolen-) Programm hängt.
Alle bis dahin aufgelaufenen Daten im StdOut brauche ich um zu sehen, was schief gelaufen ist.
Und genau da ist der Hund begraben.
Egal was ich probiere, ich bekomme keine Infos aus StdOut wenn das Programm hängt und ich es selber beenden muss.

Zum testen nehme ich das gute alte Freewae Tool PKUNZIP.EXE, welches auf eine Eingabe wartet, wenn man es ohne Parameter startet, und damit quasi ein hängendes Programm simuliert.

Mein letzter Versuch ist die Verwendung von "BeginOutputReadLine".
Aber auch da klappt es nicht.

Anbei mal der aktuelle Code.

Im aktuellen Fall ist wohl darin der Knackpunkt beschrieben:

//This event handler is not called until process is finished.
//When process is finished it gets called once for each line.

Wie kann ich das dennoch realisieren?

Hat jemand eine Idee?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.IO;
using System.Diagnostics;
using System.Threading;

namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        StringBuilder Output;

        private void button1_Click(object sender, EventArgs e)
        {
            Process p = new Process();
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardOutput = true;
            Output = new StringBuilder("");
            p.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);

            p.StartInfo.FileName = @"C:\Programme\Tools\Win\Pkunzip.exe";
            p.Start();

            p.BeginOutputReadLine();

            p.WaitForExit(2000);

            if (p.HasExited == false)
            {
                if (p.Responding)
                    p.CloseMainWindow();
                else
                    p.Kill();
            }
            p.Close();
            MessageBox.Show(Output.ToString());
        }

        private void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
        {
            //This event handler is not called until process is finished.
            //When process is finished it gets called once for each line
            if (!String.IsNullOrEmpty(outLine.Data))
                Output.Append(Environment.NewLine + outLine.Data);
        }

    }
}
07.04.2007 - 15:21 Uhr

@Golo:
Lese ich mir mal durch, danke.

@herbivore:
Habe ich mir auch qschon überlegt. Allerdings ist das ganze dann doch asynchron und wie kriege ich einen eventuellen Rückgabewert in die aufrufende Methode?
Obwohl, wo ich das gerade schreibe, meine ich mich erinnern zu können, dass es da bei Events irgendwas gab...

06.04.2007 - 21:12 Uhr

Hallo.

Ich habe vorliegend den Fall von einem Hauptobjekt mit mehreren in einem Dictionary des Hauptobjekts enthaltenen Unterobjekten.

Das Hauptobjekt durchläuft nun das Dictionary und ruft in jedem Unterobjekt eine Methode auf.
In dieser Methode kann es nun sein, dass ich eine Methode des Hauptobjekts aufrufen möchte.

Damit ich das kann, müsste ich eine Referenz des Hauptobjekts in das Unterobjekt hineinreichen.

Das birgt natürlich die Gefahr von zirkulären Refrenzen.

Wie ist für einen solchen Fall die beste Vorgehensweise?
Ich kann mir vorstellen, dass so etwas schon öfters diskuttiert wurde, aber auch nach langer Suche habe ich hier nichts finden können.

Vielleicht fehlen mir einfach nur die richtigen Stichworte zum suchen?

Gibt es evtl. ein Pattern für solche Szenarien?

Vielen Dank im Vorraus,
AtzeX

03.04.2007 - 13:53 Uhr

Danke auch dir für deine Antwort.
Ich habe gerade oben zeitgleich mit dir editiert. 😉

Edit:
Und auch hier nochmal, weils so schön ist, und ich keine Doppelpostings bauen möchte.

Mir ging gerade das Licht auf:
Ich packe einen Wertetyp in das Dictionary, erwarte jedoch, dass ich per Referenz darauf zugreifen kann.
Das geht natürlich nicht.

03.04.2007 - 13:46 Uhr

Ich glaube, du hast mich missverstanden (oder ich habe den Bezug deiner Antwort zu meinem Problem noch nicht erkannt).

Mein 'Problem' ist Folgendes (ich zitiere mich mal schnell selber):

Die von mir gefundene Möglichkeit funktioniert, ist aber aufwendiger und irgendwie nicht so 'schön'.

Habe ich vielleicht etwas übersehen/überlesen?
Geht es doch anders/einfacher?
Wie macht ihr das?

Genauer:
Ich habe ja eine Lösung gefunden, um ein Dictionary zu iterieren und die darin enthaltenen Objekte zu modifizieren:

// Loop through all MyTypes and modify the status:
string[] keys = new string[_myTypes.Keys.Count];
_myTypes.Keys.CopyTo(keys, 0);
foreach (string key in keys)
{
    MyType myType = _myTypes[key];
    myType.Status = String.Concat("Status-", myType.Format);
    _myTypes[key] = myType;
}

Nur 'gefällt' mir der Code nicht, bzw. ist deutlich aufwendiger, als der Code für den lesenden Zugriff.
Daher interessiert es mich, ob man das 'besser?' machen kann.

Ich hoffe das ist nun verständlicher.

Gruß,
AtzeX

Großes Edit:
Ich war nun einmal so 'naiv', habe aus struct class gemacht und meinen oben zitierten Code durch

foreach (MyType myType in _myTypes.Values)
{
    myType.Status = "a";
}

ausgetauscht.
Und siehe da, es funktioniert tatsächlich.
Somit ist der Zusammenhang zwischen meiner Frage und deiner Antwort auch in meinem bescheidenen kleinen Kopf hergestellt. 😁

Nur kann ich mir nicht erklären warum...
Da muss ich mal weiter wühlen.

03.04.2007 - 12:59 Uhr

Hallo.

Ich habe mir ein Beispiel erstellt, in dem ich Objekte in einem Dictionary ablege und diese nachträglich ändere.
Anbei das funktionierende Beispiel:

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Test test = new Test();
            test.Foo();
        }
    }

    class Test
    {
        private Dictionary<string, MyType> _myTypes = new Dictionary<string, MyType>(StringComparer.OrdinalIgnoreCase);

        public Test()
        {
            _myTypes.Add("a", new MyType("aa"));
            _myTypes.Add("b", new MyType("bb"));
        }

        public void Foo()
        {
            // Output with use of KeyValuePairs:
            foreach (KeyValuePair<string, MyType> keyValuePair in _myTypes)
            {
                Console.WriteLine("{0}:{1}", keyValuePair.Value.Format, keyValuePair.Value.Status);
            }

            // Loop through all MyTypes and modify the status:
            string[] keys = new string[_myTypes.Keys.Count];
            _myTypes.Keys.CopyTo(keys, 0);
            foreach (string key in keys)
            {
                MyType myType = _myTypes[key];
                myType.Status = String.Concat("Status-", myType.Format);
                _myTypes[key] = myType;
            }

            // Output with direct use of MyType:
            foreach (MyType myType in _myTypes.Values)
            {
                Console.WriteLine("{0}:{1}", myType.Format, myType.Status);
            }

            Console.ReadKey();
        }
    }    
        public struct MyType
        {
            private string _format;
            private string _status;

            public MyType(string format)
            {
                _format = format;
                _status = String.Empty;
            }

            public string Format { get { return _format; } }

            public string Status
            {
                get { return _status; }
                set { _status = value; }
            }
        }
}

Für die Ausgabe habe ich einmal zwei verschiedene Wege angewendet.
Die Möglichkeit, die im Dictionary enthaltenen Objekte während einer Iteration zu modifizieren, war jedoch nicht so schnell zu lösen und sieht auch nicht so elegant aus.

Nachdem ich hier einiges gelesen habe, wurde mir klar, warum das z.B. innerhalb einer foreach Schleife nicht geht.
Jedoch habe ich keine Beispiele gefunden WIE es denn nun anders machbar ist.

Die von mir gefundene Möglichkeit funktioniert, ist aber aufwendiger und irgendwie nicht so 'schön'.

Habe ich vielleicht etwas übersehen/überlesen?
Geht es doch anders/einfacher?
Wie macht ihr das?

Gruß und Danke im Vorraus,
AtzeX

P.S:
Wäre das nicht auch mal ein 'Top-Topic' wert?

03.04.2007 - 08:28 Uhr

Danke euch! 👍

02.04.2007 - 20:26 Uhr

Hallo.

Ich lese gerade einen Artikel. Dort heißt es

Abhilfe würden hier benutzerdefinierte Steuerelemente schaffen, bei denen die unsinnigen Schnittstellenelemente nachträglich durch den Einsatz von Attributen verborgen werden.

Kann ich in der Vererbung durch Attribute Member verbergen?

Leider finde ich nichts beim Suchen konkret darüber.

15.03.2007 - 21:26 Uhr

Danke euch.

Demnach kann ich damit ein Array deklarieren, dessen Datentyp und Dimensionen ich noch nicht kenne?

15.03.2007 - 15:26 Uhr

Hallo.

Ich habe in einem Codebeispiel folgenden Code gesehen:

Array x = foo();

"foo()" gibt also ein Array zurück, welches im Array "x" abgelegt wird.
Normalerweise deklariert man Arrays ja z.B. mittels x[] oder ähnlicher Schreibweise.

Nun wollte ich mal mehr über die im Code-Beispiel verwendete Deklarationsweise lesen, aber es ist mir nicht gelungen Infos über diese Art der Verwendung des Schlüsselwortes "Array" zu finden, da die Suche nach Array Unmengen zu Tage fördert.

Hat jemand einen Link für mich, oder kann selber etwas dazu ausführen?
Wäre nett.

Gruß,
AtzeX

07.03.2007 - 10:35 Uhr

Hallo.

Ich müsste für unser Intranet mittels lokalem Script herausfinden, welcher IE-Sicherheitszone die aktuelle Seite zugeordnet ist.

Leider ist durch googlen nichts zu finden.
Weiß jemand von euch evtl. ob das möglich ist?

13.02.2007 - 21:03 Uhr

Hm, ich hatte diese Optionen eigentlich schon durchgewühlt, nun jedoch fiel mir diese Option ins Auge:
"Automaticall format completed block on }"
Und wenn ich diese deaktiviere, verhält sich VS wie gewünscht.
Mal sehen was das an Nebenwirkungen hat.

Gruß,
AtzeX

13.02.2007 - 20:56 Uhr

Danke euch. 😉

12.02.2007 - 17:13 Uhr

Ich meine diesen Beitrag von Ikaros:

Original von ikaros
Ist nicht viel, sollte zum Verständnis aber reichen. Gibt auch noch sehr viel bessere Möglichkeiten.

  
using System;  
  
//Basisklasse für irgendwas  
public class baseClass  
{  
  private string Name;  
    
  public virtual void DoSomething()  
  {  
    // TODO:  Add baseClass.DoSomething implementation  
  }  
}  
  
//Interface für Move  
public interface IMove  
{  
  void StartMove();  
  void StopMove();  
}  
  
//Implementationen von IMove  
public class Go : IMove  
{  
  #region IMove Members  
  
  public void StartMove()  
  {  
    // TODO:  Add Go.StartMove implementation  
  }  
  
  public void StopMove()  
  {  
    // TODO:  Add Go.StopMove implementation  
  }  
  
  #endregion  
}  
  
public class Fly : IMove  
{  
  #region IMove Members  
  
  public void StartMove()  
  {  
    // TODO:  Add Fly.StartMove implementation  
  }  
  
  public void StopMove()  
  {  
    // TODO:  Add Fly.StopMove implementation  
  }  
  
  #endregion  
}  
  
//Interface für Destroy  
public interface IDestroy  
{  
  void Destroy();  
}  
  
//Implementationen von IDestroy  
public class Explosion : IDestroy  
{  
  #region IDestroy Members  
  
  public void Destroy()  
  {  
    // TODO:  Add Explosion.Destroy implementation  
  }  
  
  #endregion  
}  
  
public class Implosion : IDestroy  
{  
  #region IDestroy Members  
  
  public void Destroy()  
  {  
    // TODO:  Add Implosion.Destroy implementation  
  }  
  
  #endregion  
}  
  
  
//erbt von Basisklasse  
public class Class1 : baseClass  
{  
  //überschreibt baseClass.DoSomething  
  public override void DoSomething()  
  {  
    // TODO:  Add baseClass.DoSomething implementation  
  }  
}  
  
//erbt von Basisklasse und Interface IMove  
public class Class2 : baseClass, IMove  
{  
  //Komposition IMove-Implementation Go  
  private IMove myMove = new Go();  
  
  #region IMove Members  
  
  public void StartMove()  
  {  
    myMove.StartMove();  
  }  
  
  public void StopMove()  
  {  
    myMove.StopMove();  
  }  
  
  #endregion  
  
}  
  
//erbt von Basisklasse und Interface IMove  
public class Class3 : baseClass, IMove  
{  
  //Komposition IMove-Implementation Fly  
  private IMove myMove = new Fly();  
  
  #region IMove Members  
  
  public void StartMove()  
  {  
    myMove.StartMove();  
  }  
  
  public void StopMove()  
  {  
    myMove.StopMove();  
  }  
  
  #endregion  
  
  //überschreibt baseClass.DoSomething  
  public override void DoSomething()  
  {  
    // TODO:  Add baseClass.DoSomething implementation  
  }  
}  
//erbt von Interface IMove und IDestroy  
public class Class4 : IMove,IDestroy  
{  
  //Komposition IMove-Implementation Fly  
  private IMove myMove = new Fly();  
  
  #region IMove Members  
  
  public void StartMove()  
  {  
    myMove.StartMove();  
  }  
  
  public void StopMove()  
  {  
    myMove.StopMove();  
  }  
  
  #endregion  
  
  //Komposition IDestroy-Implementation Explosion  
  private IDestroy myDestroy = new Explosion();  
  
  #region IDestroy Members  
  
  public void Destroy()  
  {  
    myDestroy.Destroy();  
  }  
  
  #endregion  
}  
  
  

Speziell z.B. dieser Teil ist das, was mir gefällt:

//erbt von Basisklasse und Interface IMove
public class Class2 : baseClass, IMove
{
  //Komposition IMove-Implementation Go
  private IMove myMove = new Go();

  #region IMove Members

  public void StartMove()
  {
    myMove.StartMove();
  }

  public void StopMove()
  {
    myMove.StopMove();
  }

  #endregion

}

Ich kann in Class2 von einer Basisklasse ("baseClass") ableiten (mehr als eine ist nicht Sinnvoll (auch nicht möglich), wie ich gelesen und erkannt habe) und 'beliebige' Interfaces implementieren, deren Code aber aus einer vordefinierten Klasse (z.B. "Go") nutzen.
Wenn ich "Go" z.B. dynamisch durch "Fly" tauschen würde, dann wäre ich meines Verständnisses nach beim Strategy-Pattern, oder?

Oder wie nennt sich die von ihm skizzierte Technik?

12.02.2007 - 17:07 Uhr

Kann ich irgendwie vermeiden, dass VS 2005 mir automatisch den Aufruf des Basiskonstruktors in eine neue Zeile setzt?

Also statt

public frmMain(Controller controller)
    : this()

hätte ich gerne

public frmMain(Controller controller) : this()

Klar kann ich das immer von Hand 'nacheditieren', aber auf die Dauer ist das nervig.
Ich finds optisch einfach besser, wenns in einer Zeile ist.

Eine Option in VS 2005 finde ich leider nicht.

Oder kann mich jemand überzeugen, warum es in einer neuen Zeile besser aufgehoben ist (außer dem Argument der Gesamtzeilenlänge)? 😁

12.02.2007 - 15:39 Uhr

Aha. Also im Grunde Old-School Komponenten-Verwendung.

Und das im Beispiel von Ikaros nennt sich dann Strategie-Pattern, korrekt?

12.02.2007 - 15:14 Uhr

@Traumzauberbaum:
Jetzt wo mir die Möglichkeit der "Komposition" bekannt ist denke ich auch eher so. 😉

@DarKlajid:
Komposition ist doch das, was Ikaros in dem von mir im Eröffnungspost referenzierten Thread als Beispiel skizziert hat, oder?
Falls nicht würden mich Details interessieren.

11.02.2007 - 21:33 Uhr

Hallo.

Ich habe den Anwendungsfall, dass ich eigentlich mehrere abstrakte Basisklassen erstellen möchte, welche alle unterschiedliche 'Funktionspakete' darstellen und demnach Fields, Methoden und Properties mitbringen.

Nun möchte ich, dass andere (abgeleitete) Klassen diese abstrakten Klassen nutzen, also davon erben.
Das Thema wäre also 'Mehrfach Vererbung'.
Leider unterstützt .Net das ja nicht.

Interfaces können zwar mehrere implementiert werden, aber dort müsste ich ja die Funktionalität redundant implementieren.

Gibt es einen Ersatz/eine gute Idee wie ich das Lösen könnte?

Gruß und Dank,
AtzeX

Edit:
Ich glaube, ich habe hier gerade im Beitrag (Beispiel) von Ikaros eine gute Idee gefunden:
Doppelte Vererbung

Sieht eigentlich logisch und einleuchtend aus. 😉

Oder hat jemand noch eine bessere 'Idee'?

04.02.2007 - 12:25 Uhr

Kapsel die Methode "GetAdress()" in einem eigenen Typ "D".
Dieser Typ hat dann ein Feld namens "address".
Du erstellst dann eine neue Instanz von "D" und weist über einen Setter "Adresse" dann den Wert für das Feld "adresse" zu.
Dann startest du den neuen Thread mit der Instanz-Methode "GetAdress()".

Gruß,
AtzeX

07.01.2007 - 18:35 Uhr

Hi Briefkasten,

das sollte klappen:

SELECT [date], remoteadress, country FROM doc_log
WHERE DATEDIFF(day, [date], getdate()) < 7

Gruß,
AtzeX

06.01.2007 - 14:49 Uhr

Original von norman_timo

  
        #region Private Methods  
        #endregion  
  
        #region Public/Protected Methods  
        #endregion  
  

Das habe ich mir als Code-Fragment in die Toolbox gehängt, damit ich jede neue Klasse damit ausstatten kann.

Hi Norman.

Darf ich fragen, warum du Public und Protected Methods zusammenfasst?

Ich hätte eher Private und Protected zusammengefasst oder aber alle drei einzeln.

Aber vielleicht hast du ja einen guten Grund dafür?

Und was für eine Toolbox meinst du?

Gruß,
AtzeX

31.12.2006 - 18:51 Uhr

Das dachte ich auch. Leider habe ich nichts gefunden.

31.12.2006 - 10:59 Uhr

Danke dir für den Link! 😉

31.12.2006 - 10:58 Uhr

Eine Frage zu den Regions in VS2005:
Ich bevorzuge es optisch, wenn die Regions immer komplett linksbündig stehen.
Leider lässt sich das nicht konfigurieren.
VS rückt die immer wieder ein, so dass ich immer wieder selber die führenden Whitespaces entfernen muss.
Oder weiß evtl. jemand wie man es doch konfigurieren kann?

31.12.2006 - 10:57 Uhr

Hi Herbivore, danke für den Link.

Ich mache dann dort weiter. 😉

30.12.2006 - 18:02 Uhr

MZ Tools setzt niemand ein?
Und was setzen die Extrem-Poster wie Herbivore, Kleines_eichhoernchen oder Frisch ein?
Nix dergleichen?

30.12.2006 - 14:11 Uhr

Hallo.

Ich stelle wiederholt fest, dass mir in größeren Klassen/Dateien irgendwie trotz aller Bemühungen mitunter der Überblick verloren geht. 😕

Ich gruppiere eigentlich schon ziemlich viel in z.B. solchen Regionen:

#region --- Public enumerators ---

#endregion

#region --- Public structures ---

#endregion

#region --- Public properties ---

#endregion

#region --- Public methods ---

#endregion

#region --- Private methods ---

#endregion

#region --- Protected methods ---

#endregion

#region --- Public exceptions ---

#endregion

Aber trotzdem ist das irgendwie nicht das Wahre.
Wie macht ihr das denn?
Was verwendet ihr für Tricks um euch zu organisieren?

Gruß,
Atze

Edit:
Ach so, noch etwas zu den Regions in VS2005:
Ich bevorzuge es optisch, wenn die Regions immer komplett linksbündig stehen.
Leider lässt sich das nicht konfigurieren.
VS rückt die immer wieder ein, so dass ich immer wieder selber die führenden Whitespaces entfernen muss.
Oder weiß evtl. jemand wie man es doch konfigurieren kann?

30.12.2006 - 14:04 Uhr

Hallo.

Ich bin soeben über die MZ Tools gestolpert, die durchaus einige interessante Funktionalitäten aufweisen.
Preislich liegt das ja auch durchaus im Rahmen des Vertretbaren.

Setzt jemand von euch so etwas bereits ein?
Oder ähnliches Empfehlenswertes?

Gruß,
Atze

25.12.2006 - 18:56 Uhr

Hallo.

Ich suche schon geraume Zeit im Internet nach Beispielen der verschiedenen 'sichtbaren' .Net Framework Steuerelemente.

Gibt es nicht irgendwo z.B. eine Übersicht, was ich mit welchem Steuerelement machen kann?

Architektonisch gibt es ja z.B. AdventureWorks Cinema, mir geht es aber eher um die visuallen Möglichkeiten.

Ich überlege wie ich einen View am besten aufbaue, habe aber keine Übersicht, was ich alles verwenden könnte.

Beispiel-Projekte wären wirklich klasse nur kann ich nichts finden.

Hat jemand einen Tipp?

Gruß,
AtzeX

13.12.2006 - 14:15 Uhr

Hallo kleines_eichhoernchen,

ich bins noch mal.
Ich muss leider sagen, dass ich absolut nicht dazu komme mir deine Ausführungen näher anzusehen.
Ich bin sicher sie wären einen tieferen Blick wert, aber ich komme einfach nicht dazu.

Deshalb vorab noch mal vielen Dank an dich.

Irgendwann werde ich es mir ansehen.

Gruß,
Atze

11.12.2006 - 17:23 Uhr

Gutes Argument cadi.

Ich denke mal drüber nach.

Danke,
Atze

11.12.2006 - 16:38 Uhr

Hi ihr Beiden.
Danke für die Antworten.

Ihr hab Recht, das scheint aber nur dann zu gehen, wenn der Typ nicht in der Klasse definiert ist...

Wie haltet ihr das mit den Typen (in meinem Falle die Struktur), die nur in Verwendung mit einer speziellen Klasse sinnvoll ist?
Sollte man sie wie ich in der Klasse definieren um die Zusammengehörigkeit zu unterstreichen?

11.12.2006 - 09:37 Uhr

Hallo.

Ich wollte nur mal drüber reden. 😉

Ich habe eine Klasse "Device".
Darin gibt es eine Struktur namens "DeviceProperties".
Nun möchte ich eine Property gleichen Namens als Getter sowie als Setter erstellen, also auch "DeviceProperties", welche mit diesem Typ operiert.
Das geht natürlich nicht.
Logisch gesehen sind ist der Name "DeviceProperties" aber für beide, Struktur und Property, der 'optimale' Name.

Also habe ich die Struktur zwangsweise zu "DevicePropertiesData" umbenannt.
Das gefällt mir aber nicht so richtig.

Eine Alternative wäre sicherlich die Struktur aus der Klasse rauszunehmen und quasi 'parallel' zur Klasse zu definieren.
Aber ich dachte mir, die Zusammengehörigkeit wäre so deutlicher und stringenter, wenn ich die Struktur in der Klasse habe.

Was würdet ihr machen?

Gruß,
Atze

Edit:
Wenn man mal drüber redet wird es irgendwie klarer. 😁
Ich habe die Property nun zu "Properties" und die Struktur wieder zu "DeviceProperties" umbenannt.
Das ist irgendwie klarer und ich kann meine Struktur in der Klasse lassen.
Dennoch würde mich eure Meinung zum Thema interessieren, speziell auch zum Ort der Struktur: Klassenintern oder -extern ablegen?

29.11.2006 - 21:49 Uhr

Wenn du mich so fragst, denke ich nicht, dass es einen Unterschied ausmacht.
Aber ich lasse mich gerne überraschen. 🤔

29.11.2006 - 21:46 Uhr

Vielleicht noch die Windows Helpline unter anderem auch wegen der netten offline Update Packs.
Edit:
Und eine klasse Freeware-Seite: Essential Freebies
👍