2015-10-22 2 views
6

У меня есть интерфейс, который ради примера выглядит следующим образом:интерфейс Базового класса конкретизации с помощью универсального метода

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

Я тогда абстрактный базовый класс, который выглядит следующим образом:

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

Я тогда наследуют от базового класса так:

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

Как я могу создать экземпляр MyFoo сюда m общий метод с параметром типа FooBase?

Я очень много искал что-то вроде этого:

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

У меня есть проблема в том, что она хочет ввести параметры FooBase, но на самом деле я не очень волнует то, что параметры, так как мой MyFoo уже имеет эти параметры.

+0

[! Абстрактный рисунок завода на помощь] (http://www.dofactory.com/net/abstract-factory-design-pattern) – Liam

+0

@Liam Я мог бы просто быть усталым, но я не совсем понимая, как это реализовать. – Logan

+0

, и вы не хотите, чтобы подпись метода выглядела так: public static TFooClass GetFoo () '? –

ответ

3

Вы можете наследовать свой общий класс от общей базы:

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

Но вы не сможете получить доступ к MyEnum собственности с общим ограничением от FooBase. (А как бы вы, не указав тип?)

Это, или вам нужно добавить еще один параметр типа в GetFoo:

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: Еще одна вещь, которую я мог бы указать на то, что если вы найдете что вам нужно много раз называть этот метод GetFoo, то, если вы поместите его в класс экземпляра вместо статического класса, вы можете вставить один или оба из аргументов типа в класс, а не всегда указывать его в методе. Это может сделать некоторый код немного менее подробным, но на самом деле, только если вы вызовете этот метод много. Пример:

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

Вы можете выполнить следующие действия:

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

Тогда у меня нет доступа ни к чему в 'FooBase ', который мне абсолютно необходим. – Logan

Смежные вопросы