处理通用类型转换

时间:2013-05-24 02:58:08

标签: c# generics dynamic reflection

我有一个泛型类型(RoleEntity),可能会也可能不会实现通用的接口(IActor)。背景设计 在下面,但简短的故事是RoleEntity是一个可能由Actor承担的角色,而RoleEntity 可能可选 成为拥有自己角色的IActor。

因此,如果我想访问一个角色的角色,我可以想到两个选项

  1. 将角色安全地投射到演员{T}。如果我没有将一个泛型转换为另一个,我就会这样做; 似乎这样做的唯一方法就是进行一些非平凡的反思。
  2. 使用动态。
  3. 下面的代码是两者兼而有之的混合。我正在使用反射,但还不够实际找出确切的IActor {T}。然后因为我有一个不确定的类型我使用IEnumerable {dynamic}。它感觉不是很好的代码,但我不知道如何做得更好。

    有人可以提供更清洁的代码吗?

    static void GetRoleHeirarchyString<T>(IActor<T> actor)
        where T : Entity, IActor<T> 
    {
        foreach (var role in actor.AllRoles) {
            // do something with the Role;
    
            // trivial reflection
            var type = role.GetType();
            var pi = type.GetProperty("AllRoles");
            if (pi == null)
                continue;
            var roles = pi.GetValue(role, null) as IEnumerable<dynamic>;    // dynamic
            foreach (var r in roles) {
                // do something with the Role;
            }
        }
    }
    

    底色

    以下是两个接口,它们是实现Roles的解决方案的一部分。 在此设计中,可能表示为一个或多个角色的类称为Actor。表达角色的类(称为“角色”!) 使用Actor的实例来转发Actor中感兴趣的属性。例如,如果Person类是多个角色的Actor 在应用程序中,即学生,母亲和员工)然后每个角色可能会使用Person的实例来拥有一个共同的Name属性, 是基于人。

    角色可能也可能不是演员;员工可能是项目经理,甚至是雇主销售的东西的买方。但是学生 可能只是一个人的角色,而不是一个角色。

    public class RoleEntity<T> : Entity where T : Entity, IActor<T>
    {
        public T Actor { get; protected set; }
        ...
    }
    
    public interface IActor<T> where T : Entity, IActor<T>
    {
        bool AddRole(IRoleFor<T> role);
        bool RemoveRole(IRoleFor<T> role);
        bool HasRole(IRoleFor<T> role);
        IEnumerable<IRoleFor<T>> AllRoles { get; }
    }
    

1 个答案:

答案 0 :(得分:1)

有时可以定义非通用接口IRoleEntity并让RoleEntity<T>实现IRoleEntity

如果声明方法IRole.DoSomethingWithTheRole,则可以在RoleEntity<T>中实现它。 由于多态性,你可以在不知道确切的RoleEntity<T>类型的情况下调用它。

您可能希望IActor<T>继承IActor

它并不总是有意义,但我对你的问题没有足够的了解。