C# 如何判断您是在自己的构造函数中,还是在基类中';c语言中的s构造函数#

C# 如何判断您是在自己的构造函数中,还是在基类中';c语言中的s构造函数#,c#,reflection,C#,Reflection,如果一个子类正在调用它的基类Super的构造函数,有没有一种方法可以说明它不仅仅是对Super的构造函数的调用 我正在将数据从磁盘加载到对象中,我想使用反射来验证所有字段都不是空的。然而,如果我调用我的基本构造函数,那么在所有构造函数都完成之前检查它是不合适的。例如: class Super { string s; float? f; public Super(List<string> lines) { //initialize s a

如果一个子类正在调用它的基类Super的构造函数,有没有一种方法可以说明它不仅仅是对Super的构造函数的调用

我正在将数据从磁盘加载到对象中,我想使用反射来验证所有字段都不是空的。然而,如果我调用我的基本构造函数,那么在所有构造函数都完成之前检查它是不合适的。例如:

class Super
{
    string s;
    float? f;
    public Super(List<string> lines)
    {
        //initialize s and f based on lines

        if (notFromSubclassConstructor))
        { 
            AssertInitialized(this);
        }
    }

    public static void AssertInitialized(Super super)
    {
        // Iterate through every field and make sure it isnt null
        // I already know how to do this part. If we find a null
        // field we throw an exception.
    }
}

class Sub : Super
{
    string something;
    int? somethingElse;
    public Sub(List<string> lines)
        : base(lines) //we dont want to AssertInitialized inside here, we arent done yet!
    {
        //initialize blah blah

        if (notFromSubclassConstructor))
        { 
            AssertInitialized(this);
        }
    }
}
class超级
{
字符串s;
浮动?f;
公共超级(列表行)
{
//基于行初始化s和f
如果(不是来自子承包商)
{ 
断言化(这个);
}
}
公共静态无效断言(超级超级)
{
//遍历每个字段并确保它不为null
//我已经知道怎么做了,如果我们找到空的
//我们抛出一个异常。
}
}
组别:超级
{
串东西;
int?somethingElse;
公共子列表(列表行)
:base(line)//我们不想在这里断言,我们还没有完成!
{
//诸如此类
如果(不是来自子承包商)
{ 
断言化(这个);
}
}
}
我想避免传递某种布尔值来指示我来自哪里,因为这很难看。我可以通过反思或其他方式来做到这一点吗?也可以自由地提出其他范例。

您可以使用:

这将确定对象的实际类型

但实际上,我对这种模式一点也不确定。为什么不使
Super.AssertInitialized
只需检查
Super
中的字段,然后
Sub.AssertInitialized
检查
Sub
中的字段?使它们都成为私有方法,并从两个构造函数调用它们


编辑:为了清楚起见,我会让检查明确使用相关字段-不要在这里使用反射进行迭代-你知道所有字段是什么,为什么不使用它们呢?

让层次结构中的每个类检查自己的字段。如果基类构造函数中抛出异常,则派生类构造函数将永远不会运行,因为异常将直接传播到调用方


这允许每个类负责自己的数据,随着时间的推移,这些数据应该更易于维护。(它还允许您直接检查初始化,而不是试图依赖反射,反射不仅更快,而且更易于使用和写入。)

好的,或者在层次结构的最顶层类中添加数据一致性控件,或者添加一个构建对象并检查其数据的工厂。IMHO是最“清晰”的解决方案。

反射将比使用布尔运算慢得多。如果需要最后一次执行,则只需将其放在原始类构造函数的末尾,并在所有子构造函数中最后调用base()。@Steve我如何使用布尔运算来检查每个字段?这里的优点是,我可以有任何可为空的字段,并且不需要更改任何验证代码。@steve哦,我明白你的意思了。不过,这里的瓶颈是磁盘I/O,所以这并不重要。您能否分享一下关于如何基于字符串行初始化字段的逻辑?如何知道根据字符串初始化哪个字段?它是基于预先确定的顺序吗?正如Steve在他的评论中提到的,使用布尔值比使用反射更好,在这种情况下,反射可能会导致意大利面编码。@SaeedAmiri:是的,我在后面的段落中试图做到这一点。将进行编辑以澄清。@jonsket我之所以不只是检查字段,是因为我希望能够在不更改任何检查代码的情况下添加/删除字段。@MSmith:您经常添加和删除字段吗?国际海事组织称,这将对大量的法规产生影响。
if (GetType() == typeof(Super))