Reputation: 45106
Word1252_7bit
is a struct
Key
is Int32
How can I test for null if value is not found?
There is no w.Key == -1 but I don't know test for not value returned.
The last Debug line throws an exception.
List<Word1252_7bit> Words7bit = GetWord1252_7bit();
Word1252_7bit word1252_7bit ;
word1252_7bit = Words7bit.FirstOrDefault(w => w.Key == 1000);
Debug.WriteLine(word1252_7bit.Key.ToString() + " " + word1252_7bit.Value);
word1252_7bit = Words7bit.FirstOrDefault(w => w.Key == -1);
//if (word1252_7bit == null) Debug.WriteLine("word1252_7bit == null");
Debug.WriteLine( word1252_7bit.Key.ToString() + " " + word1252_7bit.Value ) ;
If I should use something other than FirstOrDefault let me know. Looking for speed searching on a unique Int32.
Not sure if it makes a difference but Key is unique and I use Key to override GetHashCode(), And to save space Key is really a piece of an UInt32
public Int32 Key
{
get
{
return (Int32)( pack[0] & ( (1<<25) - 1 ) ) ;
}
}
public struct Word1252_7bit : iWord
{
// this maps 128 values to "Windows-1252"
// this is not ASCII
// this is SQL char 8bit normalized to FormD, remove control chars, remove redactions, and cast to lower - 129 - just have to cheat on 1
private static byte[] Win1252_128to256 = new byte[] {
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, 60, 61, 62, 63
, 64, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121
,122,123,124,125,126,128,130,131,132,133,134,135,137,139,145,146,147,148,149,150,151,152,153,155,156,160,161,162,163,164,165,166
,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,215,223,230,240,247,248,254 };
private static Encoding win1252 = Encoding.GetEncoding("Windows-1252");
private UInt32[] pack;
public Int32 Key { get { return (Int32)(pack[0] & ((1 << 25) - 1)); } }
public override bool Equals(Object obj)
{
// Check for null values and compare run-time types.
if (obj == null) return false;
if (!(obj is Word1252_7bit)) return false;
Word1252_7bit comp = (Word1252_7bit)obj;
if (comp.pack == null) return false;
if (comp.pack.Count() == 0) return false;
return (comp.Key == this.Key);
}
public override int GetHashCode()
{
return Key;
}
public byte[] Bytes
{
get
{
byte b;
List<byte> bytes = new List<byte>(((pack.Length - 1) * 4) + 1);
b = (byte)((pack[0] >> 25) & ((1 << 7) - 1));
bytes.Add(Win1252_128to256[b]);
if (pack.Length > 1)
{
UInt32 cur32;
byte bits4 = 0;
byte bits3 = 0;
for (int i = 1; i < pack.Length; i++)
{
cur32 = pack[i];
if ((i-1) % 2 == 0)
{
bits4 = (byte)((cur32 >> 28) & ((1 << 4) - 1));
}
else
{ // pick up that odd i7
bits3 = (Byte)((cur32 >> 28) & ((1 << 3) - 1));
b = (byte)((UInt32)bits3 | ((UInt32)bits4 << 3));
if (b == 0) break;
bytes.Add(Win1252_128to256[b]);
}
b = (byte)(cur32 & ((1 << 7) - 1));
if (b == 0) break;
bytes.Add(Win1252_128to256[b]);
b = (byte)((cur32 >> 7) & ((1 << 7) - 1));
if (b == 0) break;
bytes.Add(Win1252_128to256[b]);
b = (byte)((cur32 >> 14) & ((1 << 7) - 1));
if (b == 0) break;
bytes.Add(Win1252_128to256[b]);
b = (byte)((cur32 >> 21) & ((1 << 7) - 1));
if (b == 0) break;
bytes.Add(Win1252_128to256[b]);
//Debug.WriteLine(win1252.GetString(bytes.ToArray()));
}
}
return bytes.ToArray();
}
}
public String Value
{
get
{
return win1252.GetString(Bytes);
}
}
public Int32 Lenght { get { return Bytes.Count(); } }
public Word1252_7bit(UInt32[] Pack)
{
if(Pack == null) throw new IndexOutOfRangeException();
if (Pack.Length == 0) throw new IndexOutOfRangeException();
pack = Pack;
}
}
Upvotes: 1
Views: 10974
Reputation: 149078
FirstOrDefault<T>
will return the first item found or the default value of T
if none is found. For reference types this is null
, but this is different for value types. For example, the default value of integers is 0
.
You can use the default
keyword:
if (word1252_7bit.Equals(default(Word1252_7bit)))
Debug.WriteLine("not found");
NOTE: You may have to write you're own override of Equals
to get the result you expect.
In general, you won't be able to distinguish an item that was not found from an item that was found but which is equal to the default value. You can do this instead:
int foundAt = Words7bit.FindIndex(w => w.Key == -1);
if (foundAt == -1)
Debug.WriteLine("not found");
else
word1252_7bit = Words7bit[foundAt];
Upvotes: 3
Reputation: 14312
To have some more control you could define your own Default
value, e.g. using something like:
public static T FirstOrDefault<T>(this IEnumerable<T> sequence, T defaultValue)
{
foreach (var element in sequence)
return element;
return defaultValue; // default(T);
// return sequence.Any() ? sequence.First() : defaultValue;
}
Then use it like
word1252_7bit = Words7bit.Where(w => w.Key == 1000)
.FirstOrDefault(Word1252_7bit.Default);
where 'Default' is a default instance defined for your struct. Something like...
public static readonly Word1252_7bit Default = new Word1252_7bit
{
Key = Int32.MinValue,
Value = "default",
};
EDIT: Improved FirstOrDefault
code (based on the original implementation)
Upvotes: 1