Создание объекта типа статического метода вызывается в цепочке наследования в C # - PullRequest
2 голосов
/ 04 декабря 2009

Я пытаюсь сделать что-то подобное в C #

public class ParentClass {
  public static ParentClass GetSomething()
  {
    var thing = new // ?????
    return thing;
  }
}

public class ChildClass : ParentClass {
}

И тогда я хочу иметь возможность вызывать статический метод дочернего класса следующим образом:

ChildClass blah = ChildClass.GetSomething();

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

ChildClass blah = (ChildClass) ChildClass.GetSomething();

Спасибо!

Ответы [ 4 ]

5 голосов
/ 04 декабря 2009

Это пахнет ужасно, но вы могли бы сделать это:

public class ParentClass {
    public static T GetSomething<T>() where T : ParentClass, new() {
        return new T();
    }
}

Использование:

ParentClass parent = ParentClass.GetSomething<ParentClass>();
ChildClass child = ChildClass.GetSomething<ChildClass>();

Это тоже законно:

ParentClass parent = ChildClass.GetSomething<ParentClass>();

, что способствует запаху этого (да, это просто составляет ParentClass parent = ParentClass.GetSomething<ParentClass>(), но все еще пахнет).

4 голосов
/ 04 декабря 2009

Эта строка:

ChildClass blah = ChildClass.GetSomething();

компилируется в точно такой же IL как эта строка:

ChildClass blah = ParentClass.GetSomething();

(когда ChildClass не объявляет собственный метод GetSomething).

Я бы предпочел:

ChildClass blah = ParentClass.GetSomething<ChildClass>();

Это похоже на вашу версию приведения, но с угловыми скобками и именем типа после, а не перед именем метода :) (По сути, предложение Джейсона, теперь я его видел!)

Однако теперь это несколько не зависит от ParentClass - вы можете определить его где угодно:

public static class FactoryUtil
{
    public static T CreateInstance<T>() where T : ParentClass
    {
        ...
    }
}

... или вы могли бы предоставить фабрику в качестве зависимости, где вам это нужно, что делает вещи более тестируемыми, потенциально ...

4 голосов
/ 04 декабря 2009

Вы не можете переопределить статические методы. Но вы можете использовать дженерики, чтобы сообщить ParentClass, какой производный класс вы имеете в виду. Это несколько уродливо, но работает:

class ParentClass<T> where T : ParentClass<T>, new()
{
    public static T GetSomething()
    {
        T thing = new T();
        return thing;
    }
}

class ChildClass : ParentClass<ChildClass>
{
}

Тест:

ChildClass x = ChildClass.GetSomething(); // works
3 голосов
/ 04 декабря 2009

C # не позволяет переопределять статические методы.

Однако ничто не мешает вам переопределить новый статический метод для ChildClass, который скрывает метод ParentClass. Поможет ли это?

...