2016-09-27 40 views
0

我試圖做到以下幾點 -作爲佔位符的接口中的C#泛型類型?

interface I1<PlaceHolder> {} 
class C1 : I1<ActualClass> { 
public Method() { ActualClass class = new ActualClass();}} 

它的工作原理,但隨後C#不允許低於 -

interface IFactory<PlaceHolder> { I1 Create<PlaceHolder>(); } 
class ConcreteFactory<ActualClass> { 
public I1 Create<ActualClass>() { return new C1(); //Won't work } 
} 

如果我嘗試添加泛型類型,以C1,則下方將無法工作

class C1<ActualClass> : I1<ActualClass> { 
    public Method() { ActualClass class = new ActualClass(); //Won't work} 
} 

我不知道是否C#允許通過其語言功能實現上述某些?

EDIT 1

請參閱下面的上方的更真實的例子(ValidationResultA和ValidationResultB是不共享一個基礎類,並且可以潛在地具有不同的屬性的具體類) -

interface IProcessor<Validator, ValidationResult> { 
ValidationResult ValidateProcess(); 
void RunProcess(); 
} 

class ProcessorA : IProcessor<ValidatorA, ValidationResultA> { 
ValidationResultA ValidateProcess() { 
    ValidatorA validator = new ValidatorA(); 
    ValidationResultA result = validator.DoSomething(); 
    result.IsAAA = true; 
    return result; 
} 

class ProcessorB : IProcessor<ValidatorB, ValidationResultB> { 
ValidationResultB ValidateProcess() { 
    ValidationResultB validator = new ValidationResultB(); 
    ValidationResultB result = validator.DoSomething(); 
    result.IsBBB = true; 
    return validator; 
} 

然後我們可以創建返回IProcess的ProcessorFactory。

我們完成了2件事 - 1.我們能夠在返回類型上重載ValidateProcess。 2.我們能夠創建IP處理器的實現,並在其中插入各種驗證器和驗證結果。

+0

您的代碼甚至沒有任何意義。你創建了一個通用的'I1 ',那麼你的代碼使用'I1'的非通用版本? –

+0

是的,想法是界面能夠在不知道PlaceHolder類型的情況下創建「合同」。子類可以用一個具體類型替代佔位符,也可以繼續使用佔位符。我試圖解決的真正問題是能夠在不創建合同的情況下創建層次結構。例如,佔位符可以是一個「Config」,每個子類可以使用它自己的Config類型(FileConfig,DBConfig等),而不需要特定的Configs子類,因爲它們可能不具有相同的方法/屬性等。 – Achilles

+0

Don' t使用接口作爲功能的標記。使用它們打算使用的接口:作爲合同的抽象。這聽起來像你正在試圖解決類型系統不打算解決的類型系統中的問題。 –

回答

1

如果你想創建一個通用型的新情況下,你需要

class MyClass<T> where T : new() 

這樣: -

interface I1<PlaceHolder> 
{   
} 
class C1<ActualClass> : I1<ActualClass> where ActualClass: new() 
{ 
    public void Method() 
    { 
     ActualClass c = new ActualClass(); 
    } 
} 

interface IFactory<PlaceHolder> where PlaceHolder : new() 
{ 
    I1<PlaceHolder> Create<PlaceHolder>(); 

} 
class ConcreteFactory<ActualClass> where ActualClass : new() 
{ 
    public I1<ActualClass> Create() 
    { 
     return new C1<ActualClass>(); 
    } 
} 
+0

謝謝。我試過了,但現在看來ActualClass的屬性已經變得無法訪問 - public void Method(){ActualClass c = new ActualClass(); c.Prop1 = 1; // Prop1不再存在} – Achilles

+1

不,它不可用,它是通用的,它不知道類有任何屬性。 actualClass可以是任何類型的! –

1

這是從你的問題你要實現什麼不清楚,但似乎像你需要通用約束來解決這個問題。有幾個不同的限制,你可以使用:

  • T必須有一個空的構造:public class MyClass<T> where T : new()
  • 牛逼繼承/實現了基類/接口:public class MyClass<T> where T : SomeOtherClass
  • T是一個類:public class MyClass<T> where T : class
  • ŧ是一個結構體:`public class MyClass where T:struct

你可以通過用逗號分隔它們來組合上面的,請記住new()約束,往往需要持續去,如:

// T must implement IDisposable, inherit from SomeClass and have a public 
// parameterless constructor 
public class MyClass<T> where T : IDisposable, SomeClass, new() 

考慮到這一點,有什麼「我認爲」你後以下解決方案:

interface I1<T> 
{ 
} 

class ActualClass 
{ 
} 

class C1 : I1<ActualClass> 
{ 
    public C1() 
    { 
     ActualClass class1 = new ActualClass(); 
    } 
} 

interface IFactory 
{ 
    I1<T> Create<T>(); 
} 

class ConcreteFactory 
{ 
    public I1<T> Create<T>() where T : I1<T>, new() 
    { 
     return new T(); 
    } 
} 

爲什麼你會想做到這一點,超越了我,但上述實施工作。你可以玩一般的限制來看看你是否解決了你的問題。

在另一種情況下,最好修改您的問題並給我們一個真實的例子。

+0

謝謝。我用一個真實世界的例子更新了這個問題。 – Achilles

1

這編譯:

interface I1<PlaceHolder> where PlaceHolder : new() { } 

class ActualClass {} 

class C1 : I1<ActualClass> 
{ 
    public void Method() { ActualClass @class = new ActualClass();} 
} 

interface IFactory<PlaceHolder> where PlaceHolder : new() 
{ 
    I1<PlaceHolder> Create(); 
} 

class ConcreteFactory : IFactory<ActualClass> 
{ 
    public I1<ActualClass> Create() { return new C1(); } 
}