检查结构的默认值

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 Arrays 和 Strings 是引用类型,因此如果它们不是 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;
}