Вызов конструктора подкласса из статического метода базового класса - PullRequest
3 голосов
/ 09 сентября 2010

Хорошо ... в Objective C вы можете создать новый подкласс из статического метода в базовом классе с помощью 'new this ()', потому что в статическом методе this указывает на класс, а не на экземпляр. Это была чертовски крутая находка, когда я впервые нашел ее и часто использовал.

Однако в C # это не работает. Черт!

Итак ... кто-нибудь знает, как я могу "создать" новый подкласс из статического метода базового класса?

Как то так ...

public class MyBaseClass{

    string name;

    public static Object GimmeOne(string name){

     // What would I replace 'this' with in C#?
        return new this(name); 

    }

    public MyBaseClass(string name){
        this.name = name;
    }

}

// No need to write redundant constructors
   public class SubClass1 : MyBaseClass{ }
   public class SubClass2 : MyBaseClass{ }
   public class SubClass3 : MyBaseClass{ }

SubClass1 foo = SubClass1.GimmeOne("I am Foo");

И да, я знаю, что могу (и обычно мог бы) просто использовать конструкторы напрямую, но у нас есть особая необходимость вызывать общего члена в базовом классе, поэтому я и спрашиваю. Опять же, цель C позволяет мне сделать это. Надеюсь, C # тоже.

Так ... кто-нибудь хочет?

Ответы [ 2 ]

6 голосов
/ 09 сентября 2010

C # не имеет точного эквивалента этому. Тем не менее, вы можете обойти это, используя ограничения общего типа, такие как:

public class MyBaseClass
{
    public string Name { get; private set; }

    public static T GimmeOne<T>(string name) where T : MyBaseClass, new()
    {
        return new T() { Name = name };
    }

    protected MyBaseClass()
    {
    }

    protected MyBaseClass(string name)
    {
        this.Name = name;
    }
}

Ограничение new () говорит, что есть конструктор без параметров - чего вы не сделали, но мы делаем его закрытым, чтобы скрыть это от потребителей. Тогда это может быть вызвано так:

var foo = SubClass1.GimmeOne<SubClass1>("I am Foo");
0 голосов
/ 09 сентября 2010

Извините, вы не можете этого сделать.C # морально против статического наследования методов.Этот метод GimmeOne никогда не будет иметь никакого другого типа, кроме MyBaseClass, и вызов его из SubClass1 не имеет значения - это все еще «действительно» вызов MyBaseClass.Библиотеки Reflection могут выполнить эту конструкцию, но вы никогда не получите из нее ничего, кроме MyBaseClass.

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

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