检查结构的默认值
Checking a structure's default value
我的 DefaultValue() 函数有问题。它总是 returns 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.");
不用担心,您的 DefaultValue()
功能很好:)
但是当你调用它时,确保你没有用空 array/string 对象初始化测试 struct
成员。 default
表示值类型的 0
(零)和引用类型的 null
。 NET Framework Array
s 和 String
s 是引用类型,因此如果它们不是 null
,函数将报告它们为非默认值。
希望这也能帮助其他人...我想出了一个解决方法来解决我的情况。在我的例子中(处理内存映射),我将一个空值传递到内存映射中,该空值最终被读取为一个空字符串 ("")。因此,我最终想出了这个函数来检查(帐户)空白字符串。这只对我有用,因为我知道如果我的字符串是空的,它们无论如何都是无效的,所以它们也可能是空的)。
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;
}
我的 DefaultValue() 函数有问题。它总是 returns 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.");
不用担心,您的 DefaultValue()
功能很好:)
但是当你调用它时,确保你没有用空 array/string 对象初始化测试 struct
成员。 default
表示值类型的 0
(零)和引用类型的 null
。 NET Framework Array
s 和 String
s 是引用类型,因此如果它们不是 null
,函数将报告它们为非默认值。
希望这也能帮助其他人...我想出了一个解决方法来解决我的情况。在我的例子中(处理内存映射),我将一个空值传递到内存映射中,该空值最终被读取为一个空字符串 ("")。因此,我最终想出了这个函数来检查(帐户)空白字符串。这只对我有用,因为我知道如果我的字符串是空的,它们无论如何都是无效的,所以它们也可能是空的)。
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;
}