2013-12-11 32 views
1

當我使用泛型接口時,這是一個普通接口的重載,我得到一個錯誤,正常接口的屬性沒有實現。如何用通用接口過載接口

實施例:

public interface IInterface1 
{ 
    string Bar1{ get; set; } 
    string Bar2{ get; set; } 
} 
public interface IInterface2 
{ 
    IInterface1 Foo{ get; } 
} 
public interface IInterface3<T>:IInterface2 where T:IInterface1 
{ 
    new T Foo { get; set; } 
} 

public class Class1<T> : IInterface3<T> where T : IInterface1 
{ 
    public T Foo { get; set; } 
} 

ERROR: 'Class1' does not implement interface member 'IInterface2.Foo'. 'Class1.Foo' cannot implement 'IInterface2.Foo' because it does not have the matching return type of 'IInterface1'.

但T是類型IInterface1的始終。我究竟做錯了什麼?

EDIT1:
如果我刪除IInterface3,我無法從我的類

EDIT2返回T:
當我改變的Class1的美孚返回,而不是牛逼IInterface1,我還是會得到一個錯誤

EDIT3:
當我改變IInterface3及1至2種方式返回相同的對象它確實有效。 我只想將Class1中的Foo和Foo1組合起來。
(順便說一句:刪除IInterface2的二傳手我並不需要它。)

解決方案:
fejesjoco的答案和裏克 - 讓我想在這最後的解決方案幫助我:

public interface IInterface1 
{ 
    string Bar1 { get; set; } 
    string Bar2 { get; set; } 
} 
public interface IInterface2 
{ 
    IInterface1 Foo { get; } 
} 
public interface IInterface3<T>:IInterface2 where T:IInterface1 
{ 
    new T Foo { get; set; } 
} 

public class Class1<T> : IInterface3<T> where T : IInterface1 
{ 
    private T _foo; 
    T IInterface3<T>.Foo { get { return _foo; } set { _foo = value; } } 
    IInterface1 IInterface2.Foo { get { return _foo; } } 
} 

public class Class1<T> : IInterface3<T> where T : IInterface1 
{ 
    public T Foo { get; set; } 
    IInterface1 IInterface2.Foo { get { return Foo; } } 
} 

的證明布丁的是在品嚐:

public class ImplemetationA : IInterface1 
{ 
    public string Bar1 { get; set; } 
    public string Bar2 { get; set; } 

    // some extra definitions here 
} 

public class ImplemetationB : IInterface1 
{ 
    public string Bar1 { get; set; } 
    public string Bar2 { get; set; } 

    // some extra definitions here 
} 

public class Problem : Class1<ImplemetationA> 
{ 
    public ImplemetationA Foo { get; set; } 
} 

public class ProblemSolved 
{ 
    public IInterface2 Method1() 
    { 
     var solvedProblem = new Problem(); 
     solvedProblem.Foo = new ImplemetationA(); 
     return solvedProblem; 
    } 
    public void Method2() 
    { 
     IInterface2 solvedProblem = Method1(); 
     var result = solvedProblem.Foo; 
    } 
} 
+0

我不太清楚你在'IInterface3'裏做了什麼,你在界面範圍內調用'new'到'T'。我從來沒有見過這種情況。這合法嗎?爲什麼你這樣做,如果你不把它存儲在一個變量? – nozzleman

回答

1

But T is always of type IInterface1

不完全是。 T將是一個實現IInterface1的類型,但它永遠不會是IInterface1。成員簽名必須完全符合接口規範。您必須實施名稱爲Foo的屬性並鍵入IInterface1。您可以使用顯式接口實現並調用其他Foo,這樣它們將以同樣的方式工作。

+0

「不完全,T將是一種實現IInterface1的類型」,這就是我所修補的。正如你在Edit3中看到的那樣,你可以返回T作爲Interface1。爲什麼它必須完全匹配?
hvk

+0

已更新:「不完全.T將是一種實現IInterface1的類型」,這就是我所修補的。正如你在Edit3中看到的那樣,你可以返回T作爲Interface1。爲什麼它必須完全匹配?原始示例中我不能使用顯式接口,因爲編譯器希望我實現這兩個接口。嗯,等待顯式調用。讓我們測試一下。是的,它的作品。 Tnx – hvk

0

編輯:我知道你在尋找的是這樣的:

public interface IInterface1 
{ 
    string Bar1{ get; set; } 
    string Bar2{ get; set; } 
} 
public interface IInterface2<T> where T : IInterface1 
{ 
    T Foo{ get; set; } 
} 

public class Class1<T> : IInterface2<T> where T : IInterface1 
{ 
    public T Foo { get; set; } 
} 

EDIT2 如果您還需要有一個非通用接口,你可以試試這個:

public interface IInterface1 
{ 
    string Bar1{ get; set; } 
    string Bar2{ get; set; } 
} 
public interface IInterface2 
{ 
    IInterface1 Foo{ get; } 
} 
public interface IInterface3<T>:IInterface2 where T:IInterface1 
{ 
    new T Foo { get; set; } // hide the non-generic IInterface2.Foo 
} 

public class Class1<T> : IInterface3<T> where T : IInterface1 
{ 
    public T Foo { get; set; } 
    IInterface1 IInterface2.Foo { get { return Foo; }} // explicitely implement IInterface2.Foo 
} 

這個編譯,但我不是100%肯定這也給出了所需的行爲。

原來的答案

我打字幾乎什麼fejesjoco已經回答了。我只想說明爲什麼這是一個問題。

考慮一些額外的課程:

public class ImplemetationA : IInterface1 
{ 
    string Bar1{ get; set; } 
    string Bar2{ get; set; } 

    // some extra definitions here 
} 

public class ImplemetationB : IInterface1 
{ 
    string Bar1{ get; set; } 
    string Bar2{ get; set; } 

    // some extra definitions here 
} 

public class Problem : Class1<ImplemetationA> 
{ 
    public ImplemetationA Foo {get; set;} 
} 

因此類Problem實現你定義它的接口。問題是Problem仍然需要實現非通用接口IInterface2。根據您的邏輯,此要求由Problem中已有的屬性Foo滿足,因爲「T始終爲IInterface1類型」。但是,發生了什麼,爲什麼我們試着這樣做:

var myProblem = new Problem(); // remember, Problem : Class1<ImplemetationA> 
var myImplB = new ImplementationB(); 
myProblem.Foo = myImplB; 

Problem實現IInterface2,由於ImplementationB實現IInterface1,這應該是允許的,但很明顯,還有這裏有一個類型的衝突,因爲有ImplemetationBImplemetationA之間的隱式轉換。

+0

Thx爲您說明答案。爲了'我的邏輯',這也不起作用,因爲myProblem.Foo是類型ImplementationA,所以myImplB不能被分配給它。在Edit3中,我顯示Foo和Foo1返回相同的對象。我只想要1個屬性而不是2. – hvk

+0

用你編輯的答案,我不能在不知道T是什麼的情況下使用IInterface2。 – hvk

+0

在這種情況下,我認爲你被你在Edit3中描述的選項卡住了。你希望能夠一般和非泛型地訪問'Foo',所以你將不得不分別實現這兩種情況。 – Rik