获取抽象类属性的默认值

问题描述 投票:0回答:2

C# 中有没有办法访问抽象类中定义的非

static
、非
const
属性的默认值?

例如,给定:

public abstract class SomeClass
{
    public int SomeProperty { get; set; } = 99;
}

我希望类似以下内容返回“

99
”:

default(SomeClass.SomeProperty);

我知道

default()
运算符不能像这样工作,上面的结果会导致编译器错误。
default()
操作符可以做的是返回
SomeClass
的默认值,对于引用类型来说自然是
null
,因此:

default(Test).SomeProperty;

可以编译,但会正确抛出

NullReferenceException

我很乐意了解以性能为代价的解决方法,例如使用反射。请注意,对于这个问题的上下文,我们需要考虑抽象类没有可用的具体实现。

我已经想象主要问题的答案是“不”。然而,如果能够从专家那里获得见解,了解该功能是否可以(或已经)考虑在 C# 中实现,或者是否存在会阻止其工作的内在语言限制,或者仅仅是它会具有以下方面的见解,那就太好了需求太稀缺,无法证明实施的合理性。

c# properties abstract-class default-value getter
2个回答
0
投票

访问此

= 99
需要:

  1. 使用 Roslyn 分析器并在构建时检查源代码
  2. 在运行时读取构造函数主体的 IL,并解释操作码
第一个选项可能更容易;您可以在

protobuf-net.BuildTools 中看到一个示例,它会检查此用法,并在没有匹配的 [DefaultValue(...)]

 时引发一个标志; a 
[DefaultValue(...)]
 在运行时检查很简单。


0
投票
您可以将该值移至常量:

public abstract class SomeClass { public const int SomePropertyDefault = 99; public int SomeProperty { get; set; } = SomePropertyDefault; }
然后您可以通过 

SomeClass.SomePropertyDefault

 访问它。

如果由于某种原因你不能,那么你可以创建自己的派生类并实例化它:

public class TestChild : SomeClass { }
然后使用它 - 

var defaultVal = new TestChild().SomeProperty;

除此之外,在不更改代码的情况下没有太多“简单”选项,因为默认值被编译到构造函数调用的一部分中。来自

反编译@sharplab.io

.method family hidebysig specialname rtspecialname instance void .ctor () cil managed { // Method begins at RVA 0x2061 // Code size 15 (0xf) .maxstack 8 IL_0000: ldarg.0 IL_0001: ldc.i4.s 99 // 99 IL_0003: stfld int32 SomeClass::'<SomeProperty>k__BackingField' // assign 99 to backing field IL_0008: ldarg.0 IL_0009: call instance void [System.Runtime]System.Object::.ctor() IL_000e: ret } // end of method SomeClass::.ctor
    
© www.soinside.com 2019 - 2024. All rights reserved.