【问题标题】:C# - Is it possible to tell whether a property has been initialized with its default value or not initialized at all?C# - 是否可以判断一个属性是否已使用其默认值初始化或根本没有初始化?
【发布时间】:2022-10-12 22:23:39
【问题描述】:

假设我们使用这个类:

public class UsefulClass
{
    public string A { get; set; }
    public string B { get; set; }
    public int? C { get; set; }
    public int? D { get; set; }
    public decimal E { get; set; }
    public decimal F { get; set; }
}

让我们考虑以下实例:

    UsefulClass z_objUsefulInstance = new UsefulClass() 
    {
        A = null,
        C = null,
        E = 0
    };

此时,z_objUsefulInstance.ACnullE为0,BDF尚未初始化。

有没有办法自动判断z_objUsefulInstance 的哪些属性尚未初始化,哪些已用null 或0 初始化?

编辑:根据大众的需求,为什么我需要这个:模拟一个类似于 EntityFramework 的数据库访问系统。现在所有属性都是一个特定的泛型类型,所以很容易知道哪个是null,哪个是Generic<T>.HasNullValue == true。但是这种泛型类型会导致各种问题,现在我们想摆脱它,尤其是当我们越来越熟悉Expressions 时。

【问题讨论】:

  • 唯一的方法必须是使用带有支持字段和额外标志的属性来了解该属性是否已设置。
  • 您是否需要允许它们在创建后初始化?否则,您可以设置设置器init。这不是你要求的,但也许是你真正需要的。
  • 所有这些都被初始化。也许不是你,而是编译器/运行时。每个字段都将由其类型的默认值初始化。
  • 为什么你需要知道这些信息?根据答案你想做什么?
  • 也许如果你解释你将如何使用这些信息,我们可以提供一个最小实现的编码示例。

标签: c# initialization


【解决方案1】:
UsefulClass z_objUsefulInstance = new UsefulClass()  {
    A = null
    C = null,
    E = 0
}; 

此时z_objUsefulInstance.AC为空,E为0, BDF 尚未初始化。

不,这不太对。

来自 C#7 语言规范中的“14.11.4 Constructor Execution

变量初始化器被转换为赋值语句,并且这些赋值语句在基类实例构造函数的调用之前执行。

因此,在上面示例中的实例构造函数开始执行之前,已分配属性

A = default(string); // null
B = default(string); // null
C = default(int?); // null
D = default(int?); // null
E = default(decimal); // 0.0m
F = default(decimal); // 0.0m

(不太准确,但足够接近这个答案)

然后运行您的实例构造函数(在此示例中,编译器提供的默认值),然后进行属性分配

A = null,
C = null,
E = 0

. E = 0E = default(decimal) 之间没有区别,nullnull 之间也没有区别(默认(字符串))。

如果您需要判断某个属性是否已设置,则必须提供一个支持字段,或者以其他方式控制对该属性的访问。

如果您想了解更多关于构造函数的详细信息,可以在https://jonskeet.uk/csharp/constructors.html 找到比语言规范更友好的摘要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-29
    • 2016-02-01
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    • 2022-08-14
    • 1970-01-01
    相关资源
    最近更新 更多