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