2013-03-03 59 views
0

這可能是一個簡單的問題,但是我無法找到一個解決方案至今...類型安全通過繼承

比方說,我有一個接口「IEntity」,由其他幾個接口來實現的。我想要的是這些接口中的每一個都實現了一種自身返回類型的方法。例如,實體「Car」應返回「ICar」,而實體「Person」應返回「IPerson」。我試圖用泛型來實現這個功能,但是沒有找到真正可接受的解決方案。

希望你能幫助我,在此先感謝。

+0

你能否闡述一下接口,請 - 特別是與指示哪些方法的目標/屬性應該返回ICAR等 – 2013-03-03 13:45:21

回答

1

通常的方法做,這是與「循環模板模式」:那麼

interface IEntity<T> where T : IEntity<T> 
{ 
    T GetSelf(); 
} 

你的實體類型實現這個接口,使用自己的類型作爲泛型參數T

public class Car : IEntity<Car> 
{ 
    Car GetSelf() { return this; } 
} 
+0

由於這是簡單,正是我想要的。我甚至輸入了這個,但'哪裏'部分看起來對我來說很奇怪,我沒有進一步嘗試...... :) – Thomas 2013-03-03 14:13:11

+3

雖然這種有點作品,我勸阻這種模式。 **它實際上並沒有產生所需的安全約束**,而且很難概念化。 (「T是一個動物的列表」很容易理解。「一個T的實體,其中T是T的一個實體」與你在現實生活中看到的任何東西都沒有對應關係。)參見http:// blogs .msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx瞭解該模式如何實現所需約束的詳細信息。 – 2013-03-03 15:53:52

1

我並不完全清楚你在做什麼,但這聽起來很接近,很簡單。

interface IEntity<T> 
{ 
    T Value { get; } 
} 

class Car : IEntity<ICar> 
{ 
    ICar Value { get; } 
} 

class Person : IEntity<IPerson> 
{ 
    IPerson Value { get; } 
} 

你需要更復雜的東西嗎?

+0

我認爲他想要「返回類型」而不是某種類型的值。 – 2013-03-03 14:04:20

1

那麼你可以用泛型很容易做到這一點,但我假設你的代碼在某個地方會處理一個IEntity而不知道編譯時的底層泛型類型。如果是這樣,那麼你可以聲明瞭兩個接口,所以:

public interface IEntity<T> : IEntity 
{ 
    new T GetThis(); 
} 

public interface IEntity 
{ 
    object GetThis(); 
} 

然後你Car可能是這個樣子:

public class Car : ICar, IEntity<ICar> 
{ 
    public ICar GetThis() 
    { 
     Console.WriteLine("Generic GetThis called"); 
     return this; 
    } 

    object IEntity.GetThis() 
    { 
     Console.WriteLine("Non-generic GetThis called"); 
     return this; 
    } 
} 

這使用Explicit Interface Implementation,因此,如果調用代碼知道這是一個Car (或者說,IEntity<ICar>),那麼它將利用通用版本。如果它只知道它是一個IEntity那麼它將利用非通用版本。

所以一些代碼,可能會利用此:

public static T SomeMethod<T>(IEntity<T> entity) 
{ 
    T target = entity.GetThis(); //Generic GetThis called 
    return target; 
} 

public static object SomeNonGenericMethod(IEntity entity) 
{ 
    object target = entity.GetThis(); //Non-generic GetThis called 
    return target; 
} 

Car car = new Car(); 
ICar icar = SomeMethod<ICar>(car); 

IEntity someEntity = new Car(); 
object obj = SomeNonGenericMethod(someEntity); 
+0

我認爲你的解決方案也很好,但我投了李的文章,因爲它足夠滿足我的需求,我不需要非通用版本的額外方法...非常感謝大量的代碼示例。 – Thomas 2013-03-03 14:18:14

0

只需添加一個返回類型爲事業的方法,它是通過在派生的接口方法返回的所有可能的類型的超類。對於您的情況:

interface IEntity { 
    IEntity SomeMethod(); 
}