繁体   English   中英

为什么必须手动创建ExpandoObject才能正确使用dynamic关键字?

[英]Why do I have to manually create ExpandoObject to properly use the dynamic keyword?

我当时在看使用“动态”抛出RuntimeBinderException的问题 我面临类似的问题:

基本上,我想在ASP.NET MVC中创建一个使用HTML动态参数的“ HTML帮助器”,类似于许多现有帮助器的htmlArguments参数(以下更多代码):

public BootstrapCell(Action<string> emitContentAction, dynamic args)

视图:

@using (grid.Cell(ViewContext.Writer.Write, new {Position = 4}))
{
     <p>zomg!</p>
}

然而,天真的方法,我得到RuntimeBinderException扔给我,声称'object' does not contain a definition for 'Position' ,即使调试和悬停在_args变量时,它显然有一个位置属性。

呼叫者和被呼叫者在单独的程序集中。 为什么会发生这个问题?

(该解决方案已在同一问题中显示: 手动创建一个ExpandoObject来容纳args。)

实现方式:

public class Cell
{
    private readonly string _tagName;
    private dynamic _args;
    private Action<string> EmitContentAction;

    public BootstrapCell(Action<string> emitContentAction, dynamic args) : DisposableBaseClass
    {
        _args = args;
        EmitContentAction = emitContentAction;
        OnContextEnter();
    }

    protected void OnContextEnter()
    {
        var sb = new StringBuilder("<");
        sb.Append(_tagName);

        if (_args.Position > 0)
        {
            sb.Append(" class=\"offset");
            sb.Append(args.Position);
            sb.Append("\"");
        }

        sb.Append(">");

        EmitContentAction(sb.ToString());
    }
}

[为了使我的问题更清楚地说明,当“显然”设置Position属性时出现了我的问题。 我知道,如果从未首先定义该属性,则必须引发异常。]

该代码存在致命缺陷。

只要您指定该属性,它就可以工作:

void Bar()
{
    Foo(new {Position = 0});
}

void Foo(dynamic args)
{
    Console.WriteLine(args.Position);
}

这将输出0 ,不会抛出RuntimeBinderException

但是,此类代码的目的是使调用者可以仅指定所需的属性,而忽略其余的属性。
您正在尝试通过if(args.Position != null)检查此遗漏。 但这不起作用,它已经需要Position存在。

当您查看还支持那些匿名配置对象的ASP.NET路由API时,您会注意到参数的类型是object而不是dynamic
使用object而不是dynamic object将使您的API可以跨程序集边界使用。

那么它是怎样工作的?

就像在链接的答案中一样,您需要手动创建属性的字典。 是否使用普通的旧Dictionary<string, object>ExpandoObject是一个优先事项。
使用ExpandoObject将使您的代码更易于读写,但这不是必需的。


关于实际得到的异常:
请注意,它告诉您在object上找不到Position属性。 如果它是缺少Position属性的匿名类型,则异常消息将不引用object而是引用匿名类型。 像这样:

'<>f__AnonymousType0'不包含'Position'的定义

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM