2012-11-06 16 views
10

Mam kilka konkretnych który wykorzystuje następujące rodzaje interfejsuklasa Fabryka powrocie rodzajowy interfejs

interface IActivity<T> 
{ 
    bool Process(T inputInfo); 
} 

klasy betonu są jak w następujący sposób

class ReportActivityManager :IActivity<DataTable> 
{ 
    public bool Process(DataTable inputInfo) 
    { 
     // Some coding here 
    } 
} 

class AnalyzerActivityManager :IActivity<string[]> 
{ 
    public bool Process(string[] inputInfo) 
    { 
     // Some coding here 
    } 
} 

Teraz jak można napisać klasy fabrycznej których retuns ogólny interfejs, taki jak IActivity.

class Factory 
{ 
    public IActivity<T> Get(string module) 
    { 
     // ... How can i code here 
    } 
} 

Dzięki

+0

Pierwsze błędzie .. error CS0050: Niezgodne dostępność: typ zwracany – Anish

Odpowiedz

14

należy utworzyć metody rodzajowe, inaczej kompilator nie będzie wiedział, rodzaj T w wartości zwracanej. Kiedy masz T będzie można tworzyć w oparciu o aktywność typu T:

class Factory 
{ 
    public IActivity<T> GetActivity<T>() 
    { 
     Type type = typeof(T); 
     if (type == typeof(DataTable)) 
      return (IActivity<T>)new ReportActivityManager(); 
     // etc 
    } 
} 

Zastosowanie:

IActivity<DataTable> activity = factory.GetActivity<DataTable>(); 
+0

Dostaję błąd „error CS0050: niespójne dostępność: typ zwracany” – Anish

+0

coraz Również nie można niejawnie przekonwertować typu „Factory.ReportActivityManager” do „Factory.IActivity ". Istnieje wyraźna konwersja (czy brakuje Ci obsady?) – Anish

+0

@Anish sorry, po prostu dodaj casting. Zaktualizowałem odpowiedź. –

1

Często jest to realizowane tak jak w lazyberezovsky's answer. W języku C++ można użyć specjalizacji szablonów, aby uzyskać błędy kompilatora podczas próby utworzenia typu, którego fabryka nie obsługuje.

Nie można tego zrobić w języku C#, ale można się zbliżyć. Chociaż kod może wyglądać trochę zaskakująco, co z kolei może być problemem.

public static class Factory { 
    public static IActivity<someType> Get(this someType self){ 
      //stuff specific to someType 
    } 

    public static IActivity<someOtherType> Get(someOtherType self){ 
      //stuff specific to someOtherType 
    } 

    public static T Creator<T>(){ 
     return null; 
    } 

} 

Wykorzystanie będzie wówczas

IActivity<someType> act = Factory.Creator<someType>().Get(); 

Oczywiście działa to tylko jeśli można przekazać typ betonu. Jeśli chcesz przekazać parametr typu, rzeczy stają się bardziej skomplikowane.

+0

Nie jestem świetny z C#, ale czy to tylko niedopatrzenie, że drugi nie jest metodą rozszerzenia? –

+0

Ponadto, w odniesieniu do "można użyć specjalizacji szablonów, aby uzyskać błędy kompilatora podczas próby utworzenia typu, którego fabryka nie obsługuje", nie można użyć ograniczeń typu, aby uzyskać błędy kompilatora, gdy fabryka otrzyma typ, który nie ma chcesz sobie poradzić? –