知道为什么 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。
为了简化案例,假设我有以下 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。