Как определить, находитесь ли вы в своем собственном конструкторе или в конструкторе базового класса в c # - PullRequest
2 голосов
/ 25 октября 2011

Если класс Sub вызывает конструктор базового класса 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);
        }
    }
}

Я бы не хотел передавать какое-то логическое значение, указывающее, откуда я, потому что это безобразно. Могу ли я сделать это как-то с помощью отражения или другими способами? Не стесняйтесь предлагать и альтернативные парадигмы.

Ответы [ 3 ]

7 голосов
/ 25 октября 2011

Ну, вы могли бы использовать:

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

Это будет определять фактический тип объекта.

Но на самом деле я совсем не уверен в этом паттерне. Почему бы не заставить Super.AssertInitialized просто проверить поля в Super, а Sub.AssertInitialized проверить поля в Sub? Сделайте их обоих закрытыми методами и вызывайте их из обоих конструкторов.

РЕДАКТИРОВАТЬ: Просто для ясности, я бы сделал проверки явно использовать соответствующие поля - не повторять с использованием отражения здесь - вы знаете, что все поля, так почему бы не использовать их?

4 голосов
/ 25 октября 2011

Просто пусть каждый класс в иерархии проверяет свои собственные поля. Если в конструкторе базового класса возникает исключение, конструктор производного класса никогда не будет запущен, так как исключение будет распространяться непосредственно на вызывающую сторону.

Это позволяет каждому классу отвечать за свои собственные данные, которые со временем должны быть более удобными в обслуживании. (Это также позволяет вам проверять инициализацию напрямую, а не пытаться полагаться на отражение, которое не только быстрее, но и проще в использовании и записи.)

1 голос
/ 25 октября 2011

Ну, или добавьте свой элемент согласованности данных в самый верхний класс в вашей иерархии, или добавьте Factory, который создает ваш объект и проверяет его данные.ИМХО самые "чистые" решения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...