知道为什么 private 属性 和 variable 在 FileHelpers 中的行为不同吗?

Any idea why private property and variable behave differently in FileHelpers?

为了简化案例,假设我有以下 class

    public class TestFileHelpersClass
    {
        [FieldOrder(1), FieldFixedLength(20), FieldTrim(TrimMode.Both)]
        public string Field1 { get; set; }

        [FieldOrder(2), FieldFixedLength(20), FieldTrim(TrimMode.Both)]
        private string Field2 { get; set; }
        // If change to a normal variable, there is no exception and FileHelper can work perfectly.
        // private string Field2;

        public TestFileHelpersClass()
        {
            this.Field1 = "Field1 Value";
            this.Field2 = "Field2 Value";
        }
    }

然后,当我实例化 FileHelperEngine 时抛出异常。

    static void TestFileHelpers()
    {
        // FileHelpers.BadUsageException: 'The field: '<Field2>k__BackingField' must be marked with the FieldFixedLength attribute because the record class is marked with FixedLengthRecord.'
        FileHelperEngine<TestFileHelpersClass> engine = new FileHelperEngine<TestFileHelpersClass>();

        TestFileHelpersClass a = new TestFileHelpersClass();

        string result = engine.WriteString(new List<TestFileHelpersClass> { a });
    }

但是 {Field2} 已经被标记为 {FieldFixedLength(20)}

如果我将 {Field2} 从 属性 更改为变量,它工作正常。

问题是:

当它是 public 时,FileHelpers 在变量和 属性 情况下都能完美工作。

私有的时候,变量还是可以的,但是属性就不行了

知道为什么私有 属性 和变量在 FileHelpers 中的行为不同吗?

当您编写 autoprops 时,编译器会为您生成支持字段:

FileHelpers 有 ReflectionHelper.cs 可以选择您希望它解析的类型的 字段 :

这意味着,对于第一个屏幕截图中我的笨蛋 class,它将选择两个 __BackingField,以及两个通常命名的字段:

当 FileHelpers 在 FieldBase.cs 中处理这些时,对于任何具有友好名称的支持字段,它适用于 属性:

fi就是__BackingField;它确实有一个友好的名称,因为它来自 PrivateProp。要获得 属性,FH 调用此:

var prop = fi.DeclaringType.GetProperty(fieldFriendlyName);

此调用 不会 发现私有 属性 因为它没有指定任何 BindingFlags.NonPublic|BindingFlags.Instance,所以 prop 最终 null 并且 FH 不会切换到查看 属性

回头看第一张图; FileHelper 自定义属性位于 属性,而不是支持字段。稍后在同一个 FieldBase.cs class 中,FH 尝试在被检查的成员上查找其自身属性的派生(FH 的属性派生自 FieldAttribute) :

被检查的成员是__BackingField,没有任何FH属性;它是具有属性的 prop。该字段确实具有属性(CompilerGenerated、DebuggerBrowsable),但因为此调用仅查找 FH 的属性 并且支持字段没有任何 FH 自定义属性,所以它实际上是在寻找错误的东西。它达到了无法工作的情况 - 它需要你放在 prop 上的属性,但它在现场查看,没有找到 FH 属性并抛出错误,因为它需要那些它永远找不到的属性。


如果 fi.DeclaringType.GetProperty(fieldFriendlyName) 改为使用重载来寻找私有道具,例如fi.DeclaringType.GetProperty(fieldFriendlyName, BindingFlags.NonPublic|BindingFlags.Instance|..other_binding_flags_here)然后它会找到你装饰的私人道具(但我不保证这是一个错误或那是解决方案)

你可以报告一个错误,看看作者是否同意,你可以自己修改库并使用修改后的版本,或者你可以只使用 fields/public props 而不是 private props


我无法回答为什么库是这样编码的;这里很少有人可以。类似的问题“开发人员 X 在想什么……”很少适合 SO。