簡體   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