Ter*_*wis 6 c# reflection exception dynamic
我有一个界面:
public abstract class Authorizer<T> where T : RequiresAuthorization
{
public AuthorizationStatus Authorize(T record)
{
// Perform authorization specific stuff
// and then hand off to an abstract method to handle T-specific stuff
// that should happen when authorization is successful
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我有一堆不同的类,它们都实现了RequiresAuthorization,相应地,Authorizer<T>每个类都有一个(我的域中的每个业务对象在授权记录后都需要不同的逻辑来执行).
我也使用UnityContainer,我注册了各种各样Authorizer<T>的.然后我有一些代码如下,从数据库中找到正确的记录并授权它:
void Authorize(RequiresAuthorization item)
{
var dbItem = ChildContainer.Resolve<IAuthorizationRepository>()
.RetrieveRequiresAuthorizationById(item.Id);
var authorizerType = type.GetType(String.Format("Foo.Authorizer`1[[{0}]], Foo",
dbItem.GetType().AssemblyQualifiedName));
dynamic authorizer = ChildContainer.Resolve(type) as dynamic;
authorizer.Authorize(dbItem);
}
Run Code Online (Sandbox Code Playgroud)
基本上,我正在使用对象上的Id从数据库中检索它.在后台,NHibernate负责确定它是什么类型的RequiresAuthorization.然后我想为它找到合适的Authorizer(我不知道在编译时Authorizer<T>我需要什么实现,所以我有一点反思来获得完全限定类型).为了实现这一点,我使用UnityContainer的Resolve方法的非泛型重载来从配置中查找正确的授权器.
最后,我想在授权器上调用Authorize,传递我从NHibernate回来的对象.
现在,针对这个问题:
在VS2010的Beta2中,上面的代码完美无缺.在RC和RTM上,一旦我进行了Authorize()调用,我就得到一个RuntimeBinderException,说"最好的重载方法匹配'Foo.Authorizer<Bar>.Authorize(Bar)'有一些无效的参数".当我在调试器中检查授权器时,它是正确的类型.当我调用GetType().GetMethods()时,我可以看到带有Bar的Authorize方法.如果我在dbItem上执行GetType(),它就是一个Bar.
因为这在Beta2而不在RC中工作,我认为这是一个回归(看起来它应该工作)并且我推迟了整理它,直到我有机会在RTM版本的C#4.0上测试它.现在我已经做到了,问题仍然存在.有没有人有任何建议让这项工作?
谢谢
特伦斯
Chr*_*ows 11
Terence,我在这里需要更多关于游戏类型及其定义的信息,以了解问题究竟是什么,但这个错误基本上告诉你它无法转换dbItem为Bar.有两种可能性:
1)RetrieveRequiresAuthorizationById()返回dynamic,因此dbItem推断出编译时类型dynamic.如果是这种情况,则运行时绑定程序将dbItem在运行时选择一种类型,如果可以找到,则该类型本质上是最佳可访问类型.在Bar给定可访问性的情况下,此类型不可转换.例如,可能是dbItem运行时类型是一些具有直接基类的不可访问类型object,并且显然object不可转换为Bar.
2)RetrieveRequiresAuthorizationById()返回一些静态类型.在这种情况下,静态类型Bar在运行时不可转换为.
我的猜测是(2)是这种情况,而类型dbItem是RequiresAuthorization.其中我也猜测是一个界面.并且这不会转换为任何类型.
如果我是对的,你想做的就是dbItem动态.如果这样做,那么运行时绑定程序将选择适当的类型dbItem,这可能是您想要执行此操作的全部原因.
void Authorize(RequiresAuthorization item)
{
var dbItem = ChildContainer.Resolve<IAuthorizationRepository>()
.RetrieveRequiresAuthorizationById(item.Id);
var authorizerType = type.GetType(String.Format("Foo.Authorizer`1[[{0}]], Foo",
dbItem.GetType().AssemblyQualifiedName));
dynamic authorizer = ChildContainer.Resolve(type) as dynamic;
authorizer.Authorize(dbItem as dynamic); // <<<Note "as" here
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4971 次 |
| 最近记录: |