0

我不明白为什么编译器认为我的 dto 在 lambda 表达式中是动态的。这是一个错误还是有正当理由?

[TestFixture]
public class DynamicTest
{
    public class Dto
    {
        public string Value { get; set; }
    }

    public Dto ToDto(dynamic d)
    {
        return new Dto();
    }

    [Test]
    public void dto_is_typed()
    {
        // var is Dto
        var dto = ToDto(new { dummy = true });
        dto.Value = "val";

        Assert.Inconclusive("yust for intellisense test");
    }

    [Test]
    public void dto_is_dynamic_inside_an_action_with_dynamic_type()
    {
        Action<dynamic> act = o =>
            {
                // dto is dynamic
                var dto = ToDto(o);
                dto.ThisIsNotAProperty = 100;
            };


        var ex = Assert.Throws<Microsoft.CSharp.RuntimeBinder.RuntimeBinderException>(() =>
            {
                act(new {dummy = true});
            });

        Assert.IsTrue(ex.Message.EndsWith("does not contain a definition for 'ThisIsNotAProperty'"));
    }
}
4

2 回答 2

4

它在 lambda 表达式中的事实有点无关紧要。你有效地得到了:

dynamic o = GetValueFromSomewhere();
var dto = ToDto(o);

现在的类型dtodynamic,因为表达式ToDto(o)是动态表达式:您使用动态值 ( o) 作为参数。即使您知道只有一种方法可以解析,但语言规则强制调用表达式的类型为dynamic.

你可以很容易地改变它,只是不使用var

Action<dynamic> act = o =>
{
    // dto is dynamic
    Dto dto = ToDto(o);
    dto.ThisIsNotAProperty = 100;
};

这现在将无法编译 - 这是我假设你想要的。

于 2013-05-03T10:11:42.273 回答
1

dto是动态的,因为它是接收动态参数的方法的返回值。
参数会导致在dynamic运行时发生重载结果,从而使编译器不知道调用的确切方法。

于 2013-05-03T10:09:12.713 回答