【问题标题】:Dealing with a Generic Type cast处理通用类型转换
【发布时间】:2013-05-19 14:05:27
【问题描述】:

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

所以如果我想访问演员角色的角色,我可以想到两个选项

  1. 将角色安全地投射到 Actor{T}。如果我不将一种泛型转换为另一种泛型,我会这样做; 似乎唯一的方法是进行一些非平凡的反思。
  2. 使用动态。

下面的代码是两者的混搭。我正在使用反射,但还不足以实际找出确切的 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 属性,该属性 是基于人的。

角色可能也可能不是演员;员工可能是项目经理,甚至可能是其雇主所售商品的买家。但是一个学生 可能只是 Person 而不是 Actor 的角色。

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; }
}

【问题讨论】:

    标签: c# generics dynamic reflection


    【解决方案1】:

    有时可以定义非通用接口IRoleEntity 并让您的RoleEntity&lt;T&gt;实现IRoleEntity

    如果您声明一个方法 IRole.DoSomethingWithTheRole,那么您可以在 RoleEntity&lt;T&gt; 中实现它。 由于多态性,您可以在不知道确切 RoleEntity&lt;T&gt; 类型的情况下调用它。

    IActor&lt;T&gt; 继承IActor 的技巧相同。

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

    【讨论】:

    • 是的,我同意。我实际上只是想在这个特定的方法中调用 RoleEntity.ToString()。然后我刚刚陷入了问题的通用转换/动态方面,并想看看如何做到这一点。我可以通过将 RoleEntity.Actor 设为对象并在每个子类中进行强制转换来避免该问题,但还没有准备好这样做。干杯!
    猜你喜欢
    • 1970-01-01
    • 2011-11-22
    • 2021-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-13
    • 1970-01-01
    相关资源
    最近更新 更多