2010-09-09 5 views
3

Ok ... dans Objective C vous pouvez créer une sous-classe à partir d'une méthode statique dans la classe de base avec 'new this()' car dans une méthode statique, 'this' fait référence à la classe, pas l'instance. C'était une super trouvaille quand je l'ai trouvé et je l'ai souvent utilisé.Appel de constructeur de sous-classe à partir de la méthode de classe de base statique

Cependant, en C# cela ne fonctionne pas. Zut! Alors ... quelqu'un sait comment je peux «créer» une sous-classe à partir d'une méthode de classe de base statique?

Quelque chose comme ça ...

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

Et oui, je sais que je peux (et ne devraient normalement) il suffit d'utiliser les constructeurs directement, mais nous avons un besoin spécifique d'appeler un membre partagé sur la classe de base c'est pourquoi je demande. Encore une fois, l'objectif C me laisse faire ça. En espérant que C# le fasse aussi.

Alors ... tout preneur?

+0

Je suis également habitué à Objective-C et essaye réellement de comprendre comment faire ceci en C++. Je suppose que si C# ne peut pas le faire, C++ ne sera pas en mesure de :( –

Répondre

6

C# n'a pas d'équivalent exact à cela. Cependant, vous pourriez potentiellement contourner ce problème en utilisant des contraintes de type générique comme ceci:

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

La nouvelle() contrainte dit qu'il est un constructeur parameterless - qui vous fait pas, mais nous le rendre privé pour cacher que des consommateurs . Alors il pourrait être invoqué comme ceci:

var foo = SubClass1.GimmeOne<SubClass1>("I am Foo"); 
+0

Man ... Je me botte moi-même! Je ne pensais même pas aux génériques, et je les utilise tout le temps! le da * n hat-switching entre C# et C++ (et Objective-C [++] d'ailleurs!) Question rapide si ... Au lieu de la contrainte 'new()' et 'return new T() {Name = name}; 'ne pourriez-vous pas faire de la contrainte quelque chose de type' MyBaseClass ', alors appelez simplement' return new T (name); '? De cette façon, vous avez toujours un bon constructeur et pas seulement une simple affectation BTW, dans votre code, pourquoi avez-vous encore besoin de 'MyBaseClass protégé (nom de la chaîne)' encore moins pourquoi l'avez-vous changé du public? – MarqueIV

+0

Je peux avoir juste rappelé quelque chose ... vous ne devez pas avoir le 'nouveau() 'constructor to' new 'quelque chose de haut? Je suppose qu'il n'y a pas moyen d'avoir une contrainte' new (string) '... ou est-ce qu'il y a – MarqueIV

+0

Correct - vous devez hve the new() contrainte dans l'ordre t o "nouveau" quelque chose. –

0

Désolé, vous ne pouvez pas faire ceci. C# est moralement opposé à l'héritage de méthode statique. Cette méthode GimmeOne n'aura jamais d'autre type que MyBaseClass, et l'appeler depuis SubClass1 n'a pas d'importance - il s'agit toujours d'un appel MyBaseClass. Les bibliothèques de Reflection pourraient faire cette construction, mais vous n'obtiendriez jamais autre chose qu'une MyBaseClass.

Si vous appelez une méthode statique, vous savez sans doute de quelle sous-classe vous l'appelez. Créer une méthode d'usine différente pour chaque sous-classe. Si vous essayez de faire cela par instance, vous devriez probablement utiliser une méthode d'usine virtuelle non statique (qui appellera automatiquement la forme la plus dérivée de la fonction, ce qui est probablement ce que vous voulez) à la place.

Questions connexes