2015-10-22 11 views
6

Ich habe eine Schnittstelle, wie dies aus Gründen Beispiel die aussieht:Schnittstelle Basisklasse Instanziierung über generische Methode

interface IFoo<TEnum> where TEnum : struct, IConvertible, IComparable, IFormattable 
{ 
    TEnum MyEnum { get; set; } 
} 

ich dann eine abstrakte Basisklasse haben, die wie folgt aussieht:

abstract class FooBase<TEnum> : IFoo<TEnum> where TEnum : struct, IConvertible, IFormattable, IComparable 
{ 
    public TEnum MyEnum { get; set; } 
} 

ich dann erben von der Basisklasse wie folgt:

class MyFoo : FooBase<MyFoo.MyFooEnum> 
{ 
    public enum MyFooEnum 
    { 
    Foo1, 
    Foo2, 
    } 
} 

Wie kann ich eine MyFoo fro instanziiert m eine generische Methode mit dem Typparameter FooBase?

ich ziemlich bin für so etwas wie folgt aussehen:

static class FooMethods 
{ 
    public static TFooClass GetFoo<TFooClass>() where TFooClass : FooBase, new() 
    { 
    TFooClass fooclass = new TFooClass(); 
    return fooclass; 
    } 
} 

Das Problem, das ich habe ist, dass es für FooBase Parameter geben will, aber da in Wirklichkeit meine ich nicht wirklich, was die Parameter MyFoo hat diese Typparameter bereits.

+0

[! Abstrakte Fabrik zur Rettung] (http://www.dofactory.com/net/abstract-factory-design-pattern) – Liam

+0

@Liam könnte ich nur müde sein, aber ich bin ich sehe nicht genau, wie ich das umsetzen würde. – Logan

+0

und Sie möchten die Methodensignatur nicht wie folgt machen 'public static TFooClass GetFoo ()'? –

Antwort

3

Sie können generische Klasse von einer gemeinsamen Basis erben:

abstract class FooBase { 
} 

abstract class FooBase<TEnum> : FooBase, IFoo<TEnum> 
where TEnum : struct, IConvertible, IFormattable, IComparable { 
    public TEnum MyEnum { get; set; } 
} 

public static TFooClass GetFoo<TFooClass>() 
where TFooClass : FooBase, new() { 
    TFooClass fooclass = new TFooClass(); 
    return fooclass; 
} 

Aber Sie zugreifen können, um die MyEnum Eigenschaft nicht mit einer allgemeinen Einschränkung von FooBase. (Und wie könnte man, ohne den Typ angegeben haben?)

Das, oder Sie benötigen eine andere Art Parameter GetFoo hinzuzufügen:

abstract class FooBase<TEnum> : IFoo<TEnum> 
where TEnum : struct, IConvertible, IFormattable, IComparable { 
    public TEnum MyEnum { get; set; } 
} 

public static TFooClass GetFoo<TFooClass, TEnum>() 
where TFooClass : FooBase<TEnum>, new() 
where TEnum : struct, IConvertible, IFormattable, IComparable { 
    TFooClass fooclass = new TFooClass(); 
    return fooclass; 
} 

UPDATE: Eine andere Sache, die ich darauf hinweisen könnte, ist, dass, wenn Sie feststellen, dass Sie diese GetFoo Methode oft aufrufen müssen, wenn Sie sie in eine Instanzklasse statt in eine statische Klasse einfügen, können Sie eines oder beide der Typargumente in die Klasse schieben, anstatt sie immer in der Methode anzugeben. Dies kann etwas Code etwas weniger ausführlich machen, aber wirklich nur, wenn Sie diese Methode viel nennen. Ex:

public sealed FooFactory<TEnum> 
where TEnum : struct, IConvertible, IFormattable, IComparable { 
    public static TFooClass GetFoo<TFooClass>() 
    where TFooClass : FooBase<TEnum>, new() { 
     TFooClass fooclass = new TFooClass(); 
     return fooclass; 
    } 
} 

... 

var factory = new FooFactory<SomeEnum>(); 
var foo1 = factory.GetFoo<SomeFooClass1>(); 
var foo2 = factory.GetFoo<SomeFooClass2>(); 

// or the other way: 

var factory = new FooFactory<SomeFooClass>(); 
var foo1 = factory.GetFoo<SomeEnum1>(); 
var foo2 = factory.GetFoo<SomeEnum2>(); 
0

können Sie als nächstes tun:

abstract class FooBase 
{ 
} 

abstract class FooBase<TEnum> : FooBase, IFoo<TEnum> where TEnum : struct, IConvertible, IFormattable, IComparable 
{ 
    public TEnum MyEnum { get; set; } 
} 

static class FooMethods 
{ 
    public static TFooClass GetFoo<TFooClass>() where TFooClass : FooBase, new() 
    { 
    TFooClass fooclass = new TFooClass(); 
    return fooclass; 
    } 
} 
+0

Dann habe ich keinen Zugriff auf irgendetwas in 'FooBase ' was ich unbedingt brauche. – Logan

Verwandte Themen