【问题标题】:Checking a structure's default value检查结构的默认值
【发布时间】:2016-03-10 07:09:37
【问题描述】:

我的 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.");

【问题讨论】:

  • 首先,发布的代码总是抛出 NRE。其次,fileInfoTwo没有被使用。
  • @IvanStoev 谢谢你,+1 的帮助。我得到了纠正,在我自己尝试以确保它编译并运行正常后,我注意到它正在工作!我的 IRL 申请仍然每次都返回 false。我认为这与我设置数组对象有关。即使我使用默认值设置它,结构本身也可能不是默认值?
  • 值类型的默认值为 0(零),引用类型的默认值为 null。如果您正在测试带有数组集的MyInfo struct,它永远不会是默认值(数组是引用类型)。
  • 谢谢你,但我只是在测试 ArrayItem 对象。我正在考虑对它做某种反思性的方法。比如比较一下&lt;T&gt;中的所有属性。
  • @IvanStoev 原来我的问题是如何定义数组项!您指出The default values are 0 (zero) for value types and null for reference types. 这让我尝试将值类型(字符串)设置为 null 而不是“”。为分数添加一个答案! ;) 再次感谢!

标签: c# generics struct .net-4.0


【解决方案1】:

不用担心,你的DefaultValue() 功能很好:)

但是当您调用它时,请确保您不要使用空数组/字符串对象初始化测试struct 成员。 default 表示 0(zero) 表示值类型,null 表示引用类型。 NET Framework Arrays 和 Strings 是引用类型,因此如果它们不是 null,函数会将它们报告为非默认值。

【讨论】:

    【解决方案2】:

    希望这也能帮助其他人......我想出了一个解决我的情况的方法。在我的情况下(处理内存映射),我将一个空值传递给一个内存映射,并且该空值最终被读取为一个空白字符串(“”)。因此,我最终想出了这个函数来检查(帐户)是否有空白字符串。这仅对我有用,因为我知道如果我的字符串为空白,它们无论如何都是无效的,所以它们也可能为空)。

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-24
      • 2010-10-19
      • 2014-01-17
      • 2016-09-19
      • 2019-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多