动态 属性 赋值抛出 RuntimeBinderException
Dynamic Property Assignment Throws RuntimeBinderException
我收到 RuntimeBinderException
消息
Cannot implicitly convert type 'object' to 'MyNamespace.SomeEnum?'. An explicit conversion exists (are you missing a cast?)
以下代码会生成该错误:
public enum SomeEnum
{
Val1
}
public class Example
{
public SomeEnum? EnumMember { get; set; }
}
public static class Program
{
static void Main()
{
dynamic example = new Example();
// Works without issue
example.EnumMember = (dynamic)Enum.Parse(typeof(SomeEnum), "Val1");
// Works without issue
example.EnumMember = Enum.Parse(example.EnumMember.GetType(), "Val1");
// Throws the aforementioned RuntimeBinderException
example.EnumMember = Enum.Parse(typeof(SomeEnum), "Val1");
}
}
为什么前两行有效(都是 return 动态类型),但第三行抛出异常(当 return 类型是对象时)?我的印象是,当分配给动态时,绑定是使用右侧的实际 运行 时间类型执行的。有人能告诉我为什么第三行不能运行吗?
第三行还需要隐式转换
example.EnumMember = (SomeEnum) Enum.Parse(typeof(SomeEnum), "Val1");
编辑
您仍然需要隐式转换的原因是因为 Enum.Parse
returns 一个对象。请参阅下面的文档。
https://msdn.microsoft.com/en-us/library/essfb559(v=vs.110).aspx
前两行 =
运算符的 RHS 表达式的编译时类型是 dynamic
。在第一种情况下,这是因为您已强制转换为 dynamic
,而在第二种情况下,这是因为您在其中一个参数中使用了动态值。
在第三种情况下,表达式的编译时类型是object
。所以你试图做相当于:
object x = Enum.Parse(typeof(SomeEnum), "Val1");
example.EnumMember = x;
那行不通,因为没有从 object
到 SomeEnum?
的 隐式 转换,这是编译器在执行时试图找到的时间。
请注意,可空性部分在这里确实不相关——它是一个枚举也与此无关。只是赋值运算符是动态绑定的,但是使用 RHS 的编译时时间。这是一个类似但更简单的示例:
class Test
{
public int Foo { get; set; }
static void Main()
{
dynamic example = new Test();
example.Foo = 10; // Fine
object o = 10;
example.Foo = o; // Bang
}
}
如果您希望编译器使用返回值的 实际 类型而不是编译时类型动态处理赋值,那么使用 dynamic
正好你想做什么 - 要么转换为动态,要么使用:
dynamic value = ...;
target.SomeProperty = value;
我收到 RuntimeBinderException
消息
Cannot implicitly convert type 'object' to 'MyNamespace.SomeEnum?'. An explicit conversion exists (are you missing a cast?)
以下代码会生成该错误:
public enum SomeEnum
{
Val1
}
public class Example
{
public SomeEnum? EnumMember { get; set; }
}
public static class Program
{
static void Main()
{
dynamic example = new Example();
// Works without issue
example.EnumMember = (dynamic)Enum.Parse(typeof(SomeEnum), "Val1");
// Works without issue
example.EnumMember = Enum.Parse(example.EnumMember.GetType(), "Val1");
// Throws the aforementioned RuntimeBinderException
example.EnumMember = Enum.Parse(typeof(SomeEnum), "Val1");
}
}
为什么前两行有效(都是 return 动态类型),但第三行抛出异常(当 return 类型是对象时)?我的印象是,当分配给动态时,绑定是使用右侧的实际 运行 时间类型执行的。有人能告诉我为什么第三行不能运行吗?
第三行还需要隐式转换
example.EnumMember = (SomeEnum) Enum.Parse(typeof(SomeEnum), "Val1");
编辑
您仍然需要隐式转换的原因是因为 Enum.Parse
returns 一个对象。请参阅下面的文档。
https://msdn.microsoft.com/en-us/library/essfb559(v=vs.110).aspx
前两行 =
运算符的 RHS 表达式的编译时类型是 dynamic
。在第一种情况下,这是因为您已强制转换为 dynamic
,而在第二种情况下,这是因为您在其中一个参数中使用了动态值。
在第三种情况下,表达式的编译时类型是object
。所以你试图做相当于:
object x = Enum.Parse(typeof(SomeEnum), "Val1");
example.EnumMember = x;
那行不通,因为没有从 object
到 SomeEnum?
的 隐式 转换,这是编译器在执行时试图找到的时间。
请注意,可空性部分在这里确实不相关——它是一个枚举也与此无关。只是赋值运算符是动态绑定的,但是使用 RHS 的编译时时间。这是一个类似但更简单的示例:
class Test
{
public int Foo { get; set; }
static void Main()
{
dynamic example = new Test();
example.Foo = 10; // Fine
object o = 10;
example.Foo = o; // Bang
}
}
如果您希望编译器使用返回值的 实际 类型而不是编译时类型动态处理赋值,那么使用 dynamic
正好你想做什么 - 要么转换为动态,要么使用:
dynamic value = ...;
target.SomeProperty = value;