|
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
byte?[] byteArray = new byte?[20];
byteArray[3] = 2;
byteArray[10] = 1;
byteArray[17] = 50;
byteArray[18] = 0;
byteArray[1] = 0;
for (int i = 0; i < byteArray.Length; i++)
{
if (((byte?)byteArray[i]).HasValue)
Console.WriteLine(String.Format("Bytearray {0} ist belegt. Wert={1}", i, byteArray[i]));
}
Console.ReadKey();
// Aber Achtung, möchtest Du beispielswiese einer normalen byte Variablen einen Wert aus dem Array zuweisen, welche keinen Wert enthält,
// so erhälst Du beim Zugriff einen Fehler
byte einByte = (byte)byteArray[12]; // Dies wird eine exception auslösen
// Du kannst entweder mit
byte einByte2 = 0;
if (byteArray[12].HasValue)
einByte2 = (byte)byteArray[12];
// darauf zugreifen, oder noch einfacher mit:
einByte2 = byteArray[12].GetValueOrDefault(0);
// GetValueOrDefault(0) gibt den Wert, falls vorhanden zurück, oder als Default die angegebene 0
}
}
}
|
Danke f. dein Code Beispiel. Ich habe es versucht und erhielt dabei die folgende Fehlermeldung:
Eine Konvertierung vom Typ 'byte?[]' in 'byte?' ist nicht möglich. (CS0030) Wie kann man das abstellen? – SaBra 30.03.2014
|
||
3 |
Das Sample von JEwen bietet dir mehrere Möglichkeiten. Bei mir funktioniert:
public NurTest() { byte?[] byteArray = new byte?[20]; byteArray[3] = 2; byteArray[10] = 1; byteArray[17] = 50; byteArray[18] = 0; byteArray[1] = 0; if (byteArray[0].HasValue) Console.WriteLine("Ja"); else Console.WriteLine("Nein"); } – Falkner 30.03.2014
|
|
1 |
Dank an alle Helfer und Mithelfer. Jetzt hab ich das verstanden. Und es geht bei mir jetzt auch fehlerfrei.
– SaBra 30.03.2014
|
|
1 |
Freut mich dass es jetzt funktioniert. Mach dem Jens doch auch noch ein +1 rein, denn er hat ja eigentlich die richtige Lösung bereits aufgezeigt.
– JEwen 30.03.2014
|
|
2 | ||
1 | ||
@JEwen: Einige Lösungsmöglichkeiten deines Codes scheinen nicht zwischen "0" und "nichts" unterscheiden zu wollen. Oder sehe ich da was falsch? Mit Falkners Snippet geht das. Oder habe ich was falsch verstanden?
– Wittgenstein 10.04.2014
|
||
@Wittgenstein: Wie Falkner schon schrieb, mehrere Möglichkeiten. Mir ging es hauptsächlich darum ihm zu zeigen wie er mit Nullable Datentypen arbeiten kann. Nein, ein explizites Beispiel auf "0" und Nichts war jetzt nicht drin, denke aber, dass dem Fragesteller mit dem Beispielcode ein möglicher Lösungsweg aufgezeigt wurde.
– JEwen 10.04.2014
|
|
Ich bekomme dann die folgende Fehlermeldung:
'byte' enthält keine Definition für 'HasValue', und es konnte keine Erweiterungsmethode 'HasValue' gefunden werden, die ein erstes Argument vom Typ 'byte' akzeptiert. – SaBra 30.03.2014
|
class Program
{
public static void Main(string[] args)
{
byte[] byteArray = new byte[20];
bool[] hv = new bool[byteArray.Length];
byte[] newBytes = {0, 244, 100, 89, 77, 33};
/*Array mit Testwerten füllen*/
ArrayClass.InsertValue(newBytes[0], 0, byteArray, hv);
ArrayClass.InsertValue(newBytes[4], 5, byteArray, hv);
ShowArray(byteArray);
/*Weil auf Index 0 bereits d. Wert 0 steht, wird nicht einfefügt*/
if(ArrayClass.InsertValue(newBytes[0], 0, byteArray, hv))
Console.WriteLine("\n\nWert wurde eingefügt!");
else
Console.WriteLine("\n\nWert konnte nicht eingefügt werden. " +
"Das Feld ist bereits besetzt!");
if(ArrayClass.InsertValue(newBytes[2], 1, byteArray, hv))
Console.WriteLine("\n\nWert wurde eingefügt!");
else
Console.WriteLine("\n\nWert konnte nicht eingefügt werden. " +
"Das Feld ist bereits besetzt!");
ShowArray(byteArray);
Console.Write("\n\nPress any key to continue . . . ");
Console.ReadKey(true);
}
/* Nur für die Ausgabe erforderlich*/
private static void ShowArray(byte[] byteArray)
{
Console.WriteLine();
for(int x = 0; x < byteArray.Length; x++)
Console.Write(byteArray[x].ToString() + " ");
}
}
internal static class ArrayClass
{
internal static bool InsertValue(byte v, int pos,
byte[] b, bool[] hv)
{
if(hv[pos])
return false;
else
{
b[pos] = v;
return (hv[pos] = true);
}
}
}
class Program
{
public static void Main(string[] args)
{
byte[] byteArray = new byte[20];
bool[] hv = new bool[byteArray.Length];
byte[] newBytes = {0, 244, 100, 89, 77, 33};
/*Array mit Testwerten füllen*/
InsertValue(0, newBytes[0], byteArray, hv);
InsertValue(5, newBytes[4], byteArray, hv);
ShowArray(byteArray);
/*Weil auf Index 0 bereits d. Wert 0 steht, wird nicht einfefügt*/
if(!HasValue(0, hv))
{
InsertValue(0, newBytes[0], byteArray, hv);
Console.WriteLine("\n\nWert wurde eingefügt!");
}
else
Console.WriteLine("\n\nWert konnte nicht eingefügt werden. " +
"Das Feld ist bereits besetzt!");
if(!HasValue(1, hv))
{
InsertValue(1, newBytes[2], byteArray, hv);
Console.WriteLine("\n\nWert wurde eingefügt!");
}
else
Console.WriteLine("\n\nWert konnte nicht eingefügt werden. " +
"Das Feld ist bereits besetzt!");
ShowArray(byteArray);
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
internal static bool HasValue(int pos, bool[] hv)
{
return hv[pos];
}
internal static void InsertValue(int pos, byte v, byte[] b, bool[] hv)
{
b[pos] = v;
hv[pos] = true;
}
/* Nur für die Ausgabe erforderlich*/
private static void ShowArray(byte[] byteArray)
{
Console.WriteLine();
for(int x = 0; x < byteArray.Length; x++)
Console.Write(byteArray[x].ToString() + " ");
}
}
|
Also ich hab hin und her überlegt und werde deine Lösung nehmen. Ich habe beschlossen deine Klasse mit meinen Funktionen zu erweitern. Das ist zwar etwas aufwendiger, aber letztendlich erspare ich mir Runtricksereien, die mit HasValue nötig wären. Danke!
– SaBra 13.04.2014
|
||
Für mich ist ein Sprachfeature (nullable Types) wesentlich handlicher und verständlicher als eine Implementierung, bei der ich auf einmal zwei 'ref' Parameter brauche. Mag mein persönlciher Geschmack sein, aber Nullables finde ich wesentlich eleganter als 'ref' Parameter.
– ffordermaier 13.04.2014
|
||
@ffordermaier: Es ist nicht zwingend nötig, ref zu benutzen, nicht einmal die Klasse...! Die betreffende Methode kann auch einfach genutzt werden. Niemand soll hier zum "BÖSEN" Wort "ref" gezwungen werden :-)
– Falkner 13.04.2014
|
||
@ffordermaier: Ich habe meiner Antwort eine weitere Möglichkeit ohne "ref" zugefügt! :-)
– Falkner 14.04.2014
|
||
Vielleicht ist es ja wirklich schon zu spät, aber ich sehe auch in der ersten Version keine Notwendigkeit für ref - das müßte auch ohne kompilieren. Das eigentliche Problem ist, dass ArrayClass keine Hoheit über seine Daten hat und sie ständig von außen hereingereicht bekommen muß. Mehr Anti-OO geht eigentlich nicht.
Und warum jetzt HasValue(1, hv) in irgendeiner Weise besser oder handlicher sein soll als arrayOfNullableBytes[1].HasValue() erschließt sich mir auch nicht. Ansonsten kann ich mich nur ffordermaier anschließen. Der Code ist für mich ein Kandidat für http://thedailywtf.com – Matthias Hlawatsch 14.04.2014
|
||
@Matthias Hlawatsch: ... kleinlaut... ich habe Mist gebaut und bin über die Anspielung v. ffordermaier nicht gestolpert. Ich habe den Code noch einmal editiert. Ich hoffe, da sind jetzt keine Fahler mehr drin! Vielen Dank für deine Zeilen!!!
Ich wollte led. eine Alternative zu HasValue bieten. Der Vorsatz der Verbesserung war nicht gemeint. – Falkner 14.04.2014
|
Aus meiner Sicht ist es irrelevant was SaBra damit vor hat, denn sie/er kann so lange nicht drauf reagieren bis festgestellt wird, ob der Wert 0 ungesetzt oder eben 0 bedeutet.
Und es wird wohl ein Byte-Array sein müssen weil es entweder eine Vorgabe gibt oder man eben kein Integer-Array mit eingehender Platzverschwendung haben möchte. Byte? ist sicher näher an Byte dran, als ein Iteger. Mit -1 zu arbeiten ist u.U. keine dauerhafte Lösung, denn es kann ja durchaus sein, dass die Anforderungen sich mit der Zeit verändern