这可能是一个简单的问题,但是我无法找到一个解决方案至今...类型安全通过继承
比方说,我有一个接口“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