Autor |
Beitrag |
mmgg
Beiträge: 41
|
Verfasst: Di 08.07.14 03:19
Wie kann man prüfen ob Value > 0 ist, wenn nicht mit if (value > 0)?
Errormessage lautet : "Der Operator ">" kann nicht auf Operanden vom Typ System.Collection.Generic.List<int> und int angewendet werden".
Ich seh nicht dass das passiert, value ist ja nicht die Liste, value ist der Wert den ich letztlich zuweise.
Wenn das nicht get, hab ich keinen Plan wie denn dann?
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| private List<int> mListe; public List<int> MyIntListe { get { return mListe; } set{ if (value != null) { mListe= value; } else { throw new Exception("You must make at least one selection\n in the 'Dividend' option box"); } } } |
Moderiert von Christian S.: Code- durch C#-Tags ersetzt
Moderiert von Th69: C#-Tags hinzugefügt
|
|
Christian S.
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Di 08.07.14 07:29
Hallo,
value ist immer der Wert, der der Property zugewiesen wird (hier: MyIntListe) und hat daher auch denselben Typ (hier: List<int>). Wovon bist Du ausgegangen, was value in Deinem Code ist?
Grüße
Christian
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
Ralf Jansen
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Di 08.07.14 09:50
Zitat: | Ich seh nicht dass das passiert, value ist ja nicht die Liste, value ist der Wert den ich letztlich zuweise. |
Doch value ist die Liste. Wenn du der List etwas hinzufügst wird nur der Getter der Property benutzt (um an die Liste zu kommen) und dann die ganz normale Add Methode von List. Wenn du einen Wert prüfen willst der der Liste hinzugefügt wird brauchst du also eine Ableitung von List mit entsprechender Prüfung. Da List ein eher abgeschlossenen Ding ist würde ich von Collection<T> ableiten und dort InsertItem überladen.
|
|
mmgg
Beiträge: 41
|
Verfasst: Di 08.07.14 22:49
@Christian
so wende ich es an
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| class Program { static void Main(string[] args) { Class1 c = new Class1(); c.MyIntListe.Add(1); c.MyIntListe.Add(2);
foreach (int tmpElm in c.MyIntListe) Console.WriteLine(tmpElm);
} } |
deswegen war ich sicher value ist eben der value. Auch weil ich value an mListe zuweise und mListe ist ja nun auch Liste
@Ralf
im geter passiert das, dann nützt mir das hier natürlich auch nichts.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| if (value != null) { if (value[0] < 0) mListe = value; } else { throw new Exception("You must make at least one selection\n in the 'Dividend' option box"); } |
spricht was dagegen es so zu machen(hab jetzt nur den getter hier reingesetzt)
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| public List<int> MyIntListe { get { if (mListe.Count > 0) { if (mListe[0] < 0) mListe.RemoveAt(0); } return mListe; } |
Ableiten bedeutet ja, ich müsste Class1 von List erben lassen, was nur solang möglich ist, wie class 1 noch nicht von was anderem ableiten soll?
Moderiert von Christian S.: Code- durch C#-Tags ersetzt
|
|
Ralf Jansen
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mi 09.07.14 10:09
class1 ist da unbeteiligt.
Hier
Zitat: | C#-Quelltext |
wird die Add Methoden von List<int> aufgerufen und nie irgendwelcher Code von class1 (mal abgesehen vom getter um an die Liste zu kommen).
Wenn wir das mal so schreiben
C#-Quelltext 1: 2:
| List<int> tmp = c.MyIntListe; tmp.Add(1); |
wird es vielleicht klarer. Es passiert absolut das gleiche. Aber man erkennt das der Aufruf von Add nur die List<int> betrifft nicht class1. Wenn du also irgendeine Prüfung brauchst dann muß sie in der Add Methode von List<int> passieren. Da das nicht geht brauchst du eine andere Listen Klasse die du in class1 als MyIntListe veröffentlichen kannst deren Add Methode aber überschreibbar ist. Das wäre zum Beispiel die erwähnte Collection<T> Klasse die zum Ableiten für solche Fälle vorbereitet ist.
|
|
Palladin007
Beiträge: 1282
Erhaltene Danke: 182
Windows 11 x64 Pro
C# (Visual Studio Preview)
|
Verfasst: Mi 09.07.14 10:36
In manchen Fällen ist es vielleicht ganz sinnvoll, ICollection<T> zu implementieren, dann hat die Klasse selber die Add-Methode und es ist folgendes Feature möglich:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| class TolleIntCollection : ICollection<int> { }
var obj = new TolleIntCollection() { 1, 2, 3 }; |
Und wer keine Lust hat, ICollection<T> selber zu implementieren (kann im Hintergrund ja eine simple Liste sein, an die die AUfrufe weiter gereicht werden), der kann dann von der Klasse Collection<T> erben.
Wenn von Collection<T> nicht geerbt werden kann (warum auch immer), dann muss wohl doch das reine Interface genommen werden.
|
|
mmgg
Beiträge: 41
|
Verfasst: Mi 09.07.14 23:00
Ich wollte mir jetzt so behelfen, dass ich eine Liste als Property ganz sein lasse, scheint einfach zuviel Balast mitzuziehen, stattdessen einfach zwei Methoden.
In der GetMyListInt Methode wird mListe nicht zugelassen: "Der Name 'mListe' existiert nicht im aktuellen Context'"
Warum das nicht? mListe ist doch letztlich eine Variable, ist im Kopf deklariet und muss doch greifbar sein an der Stelle?
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| class Class1 { private List<int> mListe; public Class1() { mListe = new List<int>(); }
public void SetMyListInt(int i) { mListe.Add(i); }
public List<int> GetMyListInt(int index) { return mListe(index); } } |
Moderiert von Christian S.: Code- durch C#-Tags ersetzt
|
|
Christian S.
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Mi 09.07.14 23:06
Du benutzt an dieser Stelle mListe aber als Funktion (nämlich mit runden Klammern dahinter, was dann aussieht wie ein Methodenparamater) und eine Funktion diesen Namens gibt es ja nicht. Du willst sicherlich den Arrayzugriff mittels eckigen Klammern.
Außerdem soll GetMyListInt wahrscheinlich keine Liste, sondern einen einzelnen Integer zurückgeben, oder?
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
Ralf Jansen
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Do 10.07.14 00:39
Denn Ballast sehe ich jetzt nicht so hoch.
So würde ich mir das vorstellen.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| class Class1 { private MyCheckedIntegerList mListe = new MyCheckedIntegerList(); public IList<int> MyIntListe { get { return mListe; } }
public class MyCheckedIntegerList : Collection<int> { public MyCheckedIntegerList() { } public MyCheckedIntegerList(IList<int> list) : base(list) { }
protected override void InsertItem(int index, int item) { if (item <= 0) throw new ArgumentOutOfRangeException("Value must be greater than 0.", "item");
base.InsertItem(index, item); } } } |
|
|
Palladin007
Beiträge: 1282
Erhaltene Danke: 182
Windows 11 x64 Pro
C# (Visual Studio Preview)
|
Verfasst: Do 10.07.14 10:36
Dafür könnte man ja theoretisch auch eine eigene Klasse schreiben, die dann einen weiteren Konstruktor anbietet und dort eine Validierungs-Funktion entegegen nimmt.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59:
| public class ValidatingList<T> : IList<T> { private readonly IList<T> _list; private readonly Predicate<T> _validate;
public int Count { get { return _list.Count; } } public bool IsReadOnly { get { return _list.IsReadOnly; } } public T this[int index] { get { return _list[index]; } set { ValidateWithException(value); _list[index] = value; } }
public ValidatingList(Predicate<T> validate) : this(new List<T>(), validate) { } public ValidatingList(IList<T> list, Predicate<T> validate) { if (validate == null) throw new ArgumentNullException("validate");
_validate = validate; _list = list ?? new List<T>(); }
public virtual bool Validate(T item) { return _validate(item); } private void ValidateWithException(T item) { if (!Validate(item)) throw new ArgumentException("invalid item"); }
public void Insert(int index, T item) { ValidateWithException(item); _list.Insert(index, item); } public void Add(T item) { ValidateWithException(item); _list.Add(item); }
} |
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| var list = new ValidatingList<string>(x => x != null);
list.Add("a"); list.Add("b"); list.Add(null); var item = "asdf"; if (list.Validate(item)) list.Add(item); |
Zuletzt bearbeitet von Palladin007 am Sa 12.07.14 22:14, insgesamt 1-mal bearbeitet
|
|
mmgg
Beiträge: 41
|
Verfasst: Do 10.07.14 22:45
Christian S. hat folgendes geschrieben : | Du benutzt an dieser Stelle mListe aber als Funktion (nämlich mit runden Klammern dahinter, was dann aussieht wie ein Methodenparamater) und eine Funktion diesen Namens gibt es ja nicht. Du willst sicherlich den Arrayzugriff mittels eckigen Klammern.
Außerdem soll GetMyListInt wahrscheinlich keine Liste, sondern einen einzelnen Integer zurückgeben, oder? |
besten dank, genau das wars. Und dann muss natürllich die Function typ int zurückgeben, statt List<int>.
@all
thanks für dei Beispiele.
Eine Liste als property kuck ich mir nochmal an, den mit den zwei Methoden kann man später zum auslesen kein foreach nehmen.
|
|
mmgg
Beiträge: 41
|
Verfasst: Do 10.07.14 22:59
Ich bin gerade dabei, hab also Palladin007 Code eingefügt, und es heisst für diese Zeile:
"does not implementäte interface member System.Collections.Generic.IList"
Warum das, es fehlt kein Namensraum
"using System.Collections.Generic;" ist dabei.
Und mehr als die Schnittstelle dann da anzuhängen, geht doch nicht?
|
|
Ralf Jansen
Beiträge: 4705
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Do 10.07.14 23:47
Er hat nicht alle Methoden von IList<T> implementiert sondern nur die wichtigsten um dir das Verfahren zu zeigen. Drum der Codekommentar '// IList<T>-Implementierungen ...' am Ende.
Wenn du im Editor mal auf IList<T> das Contextmenü öffnest sollte du den erste Eintrag 'Implement Interface' (oder eben das deutschsprachige Äquivalent wenn du ein deutsches Visual Studio verwendest) mal ausführen. Das generiert dir dann die noch fehlenden Methoden die du dann im Anschluss mit sinnvollem Code füllen musst. Läuft im Prinzip darauf hinaus in diesen Methoden den Aufruf an die jeweilige gleichnamige Methode von _list weiterzuleiten.
|
|
mmgg
Beiträge: 41
|
Verfasst: Sa 12.07.14 20:57
das ging auf anhieb, danke dafür.
Ich kann die Klasse "ValidatingList" bis jetzt nicht anwenden.
Der Error passeirt in dieser Zeile: _list.Add(item);
C#-Quelltext 1: 2: 3: 4: 5:
| public void Add(T item) { ValidateWithException(item); _list.Add(item); } |
Die Errormessage heisst zwar "... wurde nicht auf eine Objectinstanz festgelegt", aber IList ist eine abstracte Klasse, kann also nicht initzialisiert werden?
Moderiert von Christian S.: Code- durch C#-Tags ersetzt
|
|
Palladin007
Beiträge: 1282
Erhaltene Danke: 182
Windows 11 x64 Pro
C# (Visual Studio Preview)
|
Verfasst: Sa 12.07.14 22:12
Ach sie an, ich hab vergessen, _list zu instanziieren.
Musst du halt im Konstruktor noch machen. Setze den list-Parameter im zweiten Konstruktor, vergiss aber nicht zu prüfen, ob der null ist und wenn ja, erstelle eine neue Liste.
|
|
mmgg
Beiträge: 41
|
Verfasst: Di 15.07.14 22:10
Hi Palladin,
das war auch mein erster Gedanke, aber ILIst ist eine abstrakte Klasse, kann also nicht initialisiert werden.
|
|
Palladin007
Beiträge: 1282
Erhaltene Danke: 182
Windows 11 x64 Pro
C# (Visual Studio Preview)
|
Verfasst: Di 15.07.14 22:23
IList ist ein Interface und List implementiert dieses Interface.
Du solltest dringend die Grundlagen nacholen
Auf galileo computing gibts ein Buch, das nennt sich Visual C# 2012
|
|
mmgg
Beiträge: 41
|
Verfasst: Mi 16.07.14 03:12
Glaub ich nicht, ich würd ja auch keinen Mathe-Prof zurück auf die Schulbank schicken, weil er sich v-e-r-r-e-c-h-n-e-t hat.
Ich wünschte ich hätte diese Antwort voher gelesen, bevor ich den andern Thread nochmal angeschoben hab.
Diese Antwort hier, ist wahrscheinlich wieder so' ne schlimme Antwort, die weitere Antworter vorenthält?
By the way, die Post-Frequenz in solchen Foren war schon mal höher.
|
|
Christian S.
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Mi 16.07.14 07:43
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
Palladin007
Beiträge: 1282
Erhaltene Danke: 182
Windows 11 x64 Pro
C# (Visual Studio Preview)
|
Verfasst: Mi 16.07.14 08:55
Es geht ja auch nicht einmal darum, dass du dich "verrechnet" hast, sondern dass du nicht die nötigen Mittel kennst, damit du dich nicht "verrechnest".
Einen Mathe-Prof würdest du wahrcheinlich doch auf die Schulbank schicken, wenn er die Formeln und Rechenwege nicht kennt, oder?
|
|