在通用接口上获得通用成员

时间:2012-11-20 11:24:18

标签: c# generics interface

我的应用程序中的每个实体类都必须实现以下接口:

public interface IEntity<T> {
    T Id { get; set; }
}

几乎100%的时间T的类型都是int。但是我必须处理的情况是id可能是复合id。例如。我可以有以下实现:

public class User : IEntity<int> {
    public int Id { get; set; }
    ...
}

public class Site : IEntity<int> {
    public int Id { get; set; }
    ...
}

public class UserSite : IEntity<UserSiteIdentifier> {
    public UserSiteIdentifier Id { get; set; }
    ...
}

// Note: IIdentifier doesn't have any members
public class UserSiteIdentifier : IIdentifier {
    public User User { get; set; }
    public Site Site { get; set; }
    ...

    public override ToString() {
        return User.Id + "|" + Site.Id;
    }
}

现在给定一个实体实例(其中类型未知)我需要检索id并将其转换为字符串。我可以说:

object entity = ???;
string id;

if (entity is IEntity<int>)
    id = ((IEntity<int>)entity).Id.ToString();
else if (entity is IEntity<IIdentifier>)
    id = ((IEntity<IIdentifier>)entity).Id.ToString();

但是这段代码并不适合我,因为我必须重复几乎相同的代码来处理复合id。

如果有人能给我一个更清洁的解决方案,我会很感激。这个应用程序仍然是一个原型,完全开放的建议。感谢

1 个答案:

答案 0 :(得分:1)

您可以介绍IEntity界面:

public interface IEntity<T>:IEntity {
    new T Id { get; set; }
}

 public interface IEntity {
    object Id { get; }
}

在实现两个应该返回相同值的属性时会有一些不便,但这可以通过引入隐藏Entity<T>属性的基类object Id来克服。

public class Entity<T>:IEntity<T> {
    public T Id { get; set; }
    object IEntity.Id { get{ return Id;}  }
}

然后你的问题代码可能是:

object value =...;
var entity = value as IEntity;
string id;
if(entity != null)
    id = entity.Id.ToString();