Lucina
Lucina

Reputation: 490

How to tell if you are in your own constructor, or your base class's constructor in c#

If a class Sub is calling its base class Super's constructor, is there a way to tell that it is not just a call to Super's constructor alone?

I am loading in data from the disk into objects, and I would like to verify that all fields are not null using reflection. However, if I am calling my base constructor, then it isn't appropriate to check this until all constructors are finished. Example:

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);
        }
    }
}

I would like to avoid passing some sort of boolean indicating where I'm coming from since that's ugly. Can I do this somehow with reflection or by other means? Feel free to suggest alternative paradigms too.

Upvotes: 2

Views: 262

Answers (3)

Tigran
Tigran

Reputation: 62265

Well, or add your data consistency control in top most class in your hierarchy, or add a Factory, that constructs your object, and checks its data. IMHO are most "clear" solutions.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1503100

Well you could use:

if (GetType() == typeof(Super))

That will determine the actual type of the object.

But really I'm not at all sure about this pattern anyway. Why not make Super.AssertInitialized just check the fields in Super, and Sub.AssertInitialized check the fields in Sub? Make them both private methods, and call them from both constructors.

EDIT: Just to be clear, I would make the checks explicitly use the relevant fields - don't iterate using reflection here - you know what all the fields are, so why not use them?

Upvotes: 7

Reed Copsey
Reed Copsey

Reputation: 564771

Just have each class in the hierarchy check its own fields. If an exception is thrown in the base class constructor, the derived class constructor will never run, as the exception will propagate to the caller directly.

This allows each class to be responsible for its own data, which should be more maintainable over time. (It also allows you to check the initialization directly instead of trying to rely on reflection, which is not only faster, but simpler to use and write.)

Upvotes: 4

Related Questions