C# 处理泛型类型转换

C# 处理泛型类型转换,c#,generics,dynamic,reflection,C#,Generics,Dynamic,Reflection,我有一个泛型类型(RoleEntity),它可能实现也可能不实现泛型接口(IActor)。设计背景 下面是一个简短的故事,角色扮演是一个可能由演员扮演的角色,角色扮演可能是可选的 做一个有自己角色的IActor 因此,如果我想访问演员角色的角色,我可以考虑两种选择 将角色安全地分配给演员{T}。这是我会做的,如果我不是铸造一个通用到另一个;似乎唯一的方法就是进行一些非琐碎的反思 使用动态 下面的代码是两者的混搭。我正在使用反射,但距离实际计算出确切的IActor{T}还不够远。因为我有一个不确定

我有一个泛型类型(RoleEntity),它可能实现也可能不实现泛型接口(IActor)。设计背景 下面是一个简短的故事,角色扮演是一个可能由演员扮演的角色,角色扮演可能是可选的 做一个有自己角色的IActor

因此,如果我想访问演员角色的角色,我可以考虑两种选择

  • 将角色安全地分配给演员{T}。这是我会做的,如果我不是铸造一个通用到另一个;似乎唯一的方法就是进行一些非琐碎的反思
  • 使用动态 下面的代码是两者的混搭。我正在使用反射,但距离实际计算出确切的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;
            }
        }
    }
    
    静态无效GetRoleHeirarchyString(IActor演员)
    其中T:实体,IActor
    {
    foreach(actor.AllRoles中的var角色){
    //对角色做些什么;
    //琐碎的反映
    var type=role.GetType();
    var pi=type.GetProperty(“所有角色”);
    if(pi==null)
    继续;
    var roles=pi.GetValue(role,null)作为IEnumerable;//动态
    foreach(角色中的var r){
    //对角色做些什么;
    }
    }
    }
    
    回击 下面是两个接口,它们是实现的解决方案的一部分。 在这种设计中,可以表示为一个或多个角色的类称为参与者。表示角色的类(称为“角色”!) 使用参与者的实例转发参与者感兴趣的属性。例如,如果一个人类是多个角色的参与者 在应用程序中)例如,学生、母亲和员工),则每个角色都可以使用该人员的一个实例来拥有一个公共名称属性 是基于人的

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

    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; }
    }
    
    公共类角色属性:实体,其中T:实体,IActor
    {
    公共T参与者{get;受保护集;}
    ...
    }
    公共接口IActor,其中T:实体,IActor
    {
    bool-AddRole(IRoleFor-role);
    bool-removole(IRoleFor角色);
    布尔·哈斯罗尔(IRoleFor role);
    IEnumerable所有角色{get;}
    }
    
    有时可以定义非通用接口
    IRoleEntity
    ,并让您的
    角色属性实现
    IRoleEntity

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

    使用
    IActor
    继承
    IActor
    时可能需要使用的相同技巧


    这并不总是有道理的,但我对你的问题理解不够。

    是的,我同意。实际上,我只想在这个特定的方法中调用RoleEntity.ToString()。然后我就陷入了问题的一般铸造/动态方面,想看看如何做到这一点。我还可以通过将RoleEntity.Actor设置为一个对象并在每个子类中强制转换来避免这个问题,但还没有准备好这样做。干杯