這可能是一個簡單的問題,但是我無法找到一個解決方案至今...類型安全通過繼承
比方說,我有一個接口「IEntity」,由其他幾個接口來實現的。我想要的是這些接口中的每一個都實現了一種自身返回類型的方法。例如,實體「Car」應返回「ICar」,而實體「Person」應返回「IPerson」。我試圖用泛型來實現這個功能,但是沒有找到真正可接受的解決方案。
希望你能幫助我,在此先感謝。
這可能是一個簡單的問題,但是我無法找到一個解決方案至今...類型安全通過繼承
比方說,我有一個接口「IEntity」,由其他幾個接口來實現的。我想要的是這些接口中的每一個都實現了一種自身返回類型的方法。例如,實體「Car」應返回「ICar」,而實體「Person」應返回「IPerson」。我試圖用泛型來實現這個功能,但是沒有找到真正可接受的解決方案。
希望你能幫助我,在此先感謝。
通常的方法做,這是與「循環模板模式」:那麼
interface IEntity<T> where T : IEntity<T>
{
T GetSelf();
}
你的實體類型實現這個接口,使用自己的類型作爲泛型參數T
:
public class Car : IEntity<Car>
{
Car GetSelf() { return this; }
}
由於這是簡單,正是我想要的。我甚至輸入了這個,但'哪裏'部分看起來對我來說很奇怪,我沒有進一步嘗試...... :) – Thomas 2013-03-03 14:13:11
雖然這種有點作品,我勸阻這種模式。 **它實際上並沒有產生所需的安全約束**,而且很難概念化。 (「T是一個動物的列表」很容易理解。「一個T的實體,其中T是T的一個實體」與你在現實生活中看到的任何東西都沒有對應關係。)參見http:// blogs .msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx瞭解該模式如何實現所需約束的詳細信息。 – 2013-03-03 15:53:52
我並不完全清楚你在做什麼,但這聽起來很接近,很簡單。
interface IEntity<T>
{
T Value { get; }
}
class Car : IEntity<ICar>
{
ICar Value { get; }
}
class Person : IEntity<IPerson>
{
IPerson Value { get; }
}
你需要更復雜的東西嗎?
我認爲他想要「返回類型」而不是某種類型的值。 – 2013-03-03 14:04:20
那麼你可以用泛型很容易做到這一點,但我假設你的代碼在某個地方會處理一個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);
我認爲你的解決方案也很好,但我投了李的文章,因爲它足夠滿足我的需求,我不需要非通用版本的額外方法...非常感謝大量的代碼示例。 – Thomas 2013-03-03 14:18:14
只需添加一個返回類型爲事業的方法,它是通過在派生的接口方法返回的所有可能的類型的超類。對於您的情況:
interface IEntity {
IEntity SomeMethod();
}
你能否闡述一下接口,請 - 特別是與指示哪些方法的目標/屬性應該返回ICAR等 – 2013-03-03 13:45:21