2013-03-03 60 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(); 
}