2016-03-09 4 views
0

В моей функции DefaultValue() есть что-то не так. Он ВСЕГДА возвращает false, представляя, что структура НЕ является значением по умолчанию.Проверка значения по умолчанию для структуры

Почему это не работает?

[StructLayout(LayoutKind.Sequential)] 
private struct ArrayItem 
{ 
    public long SrcSize; 

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 250)] 
    public string SrcFile; 

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 250)] 
    public string DestFile; 
} 

[StructLayout(LayoutKind.Sequential)] 
private struct MyInfo 
{ 
    public int Count; 

    public int AppOne; 

    public int AppTwo; 

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100, ArraySubType = UnmanagedType.Struct)] 
    public ArrayItem[] Files; 
} 


private bool DefaultValue<T>(T structure) 
{ 
    if (EqualityComparer<T>.Default.Equals(structure, default(T))) 
     return true; 
    else 
     return false; 
} 

//Success returns 'Value Changed' as expected 
MyInfo fileInfoOne = new MyInfo(); 
fileInfoOne.Count = 3; 
fileInfoOne.Files = new ArrayItem[100]; 
fileInfoOne.Files[0].SrcSize = 100; 
Debug.Write("fileInfoOne: "); 
if (DefaultValue(fileInfoOne.Files[0])) Debug.WriteLine("Default Value."); else Debug.WriteLine("Value Changed."); 


//Fails but has all the default settings, should return 'Default Value' 
MyInfo fileInfoTwo = new MyInfo(); 
fileInfoTwo.Files = new ArrayItem[100]; 
fileInfoTwo.Files[0].SrcSize = 0; 
fileInfoTwo.Files[0].SrcFile = ""; 
fileInfoTwo.Files[0].DestFile = ""; 
Debug.Write("fileInfoTwo: "); 
if (DefaultValue(fileInfoTwo.Files[0])) Debug.WriteLine("Default Value."); else Debug.WriteLine("Value Changed."); 
+2

Прежде всего, выложенный код всегда выбрасывает NRE. Во-вторых, 'fileInfoTwo' не используется. –

+0

@ ИванСтоев благодарит за это, +1 за помощь. Я исправил его и попробовал сам убедиться, что он скомпилирован и работает нормально. Я заметил, что он работает! Мое приложение IRL все равно возвращает false каждый раз. Я думаю, что это связано с тем, что я устанавливаю объект массива. Даже если я устанавливаю его со значениями по умолчанию, сама структура, возможно, не является дефолтом? –

+0

Значения по умолчанию: 0 (ноль) для типов значений и 'null' для ссылочных типов. Если вы тестируете структуру MyInfo' с массивом, она никогда не будет использоваться по умолчанию (массив является ссылочным типом). –

ответ

2

Отсутствие беспокойства, ваша DefaultValue() функции просто отлично :)

Но когда ты зовешь его, убедитесь, что вы не инициализировать тест struct пользователей с пустым массивом/строковыми объектами. default означает 0 (ноль) для типов значений и null для ссылочных типов. NET Framework Array s и String s являются ссылочными типами, поэтому, если они не являются null, функция сообщит о них как не умолчанию.

0

В надежде, это может помочь кому-то еще ... Я придумал работу для своей ситуации. В моем случае (имея дело с отображением памяти) я передаю нулевое значение в карту памяти, и это нулевое значение в конце концов считывается как пустая строка (""). Из-за этого я закончил эту функцию, чтобы проверить (учетную запись) на пустые строки. Это работает только для меня, потому что я знаю, что если моя строка пустая, они все равно недействительны, поэтому они могут быть нулевыми).

private bool NoFile<T>(T structure) 
{ 
    bool valueIsDefault = true; 

    foreach (FieldInfo f in typeof(T).GetFields()) 
    { 
     object defaultVal = f.GetValue(default(T)); 
     object structVal = f.GetValue(structure); 
     if (structVal.GetType() == typeof(string) && (string)structVal == "") structVal = null; 

     if (!object.Equals(structVal, defaultVal)) 
     { 
      valueIsDefault = false; 
      break; 
     } 
    } 

    return valueIsDefault; 
} 
Смежные вопросы