未记录的Object.Value来自.NET?
是方法还是财产?它的目的是什么?
当我写的东西(VB.NET WinForms ...没有尝试过C#)时:
TextBox1.Text = ListBox1.SelectedItem.Value
我收到错误:
Option Strict On disallows late binding.
但是,如果没有Option Strict On,它似乎只是返回对象的值。
Object类上下文中的'Value'的任何文档或解释?
**这个问题与错误无关。这用作上下文的一个例子。它是关于对象类的Value方法/属性是什么? **
答案 0 :(得分:2)
在.NET中,没有名为Value in Object的属性或方法。
VB.NET处理Object.Value
的方式显然特定于该语言。
例如,在C#中,以下代码甚至不会编译:
Object o=new Object();
Console.WriteLine(o.Value);
出现此错误:
“'object'不包含'Value'的定义,也没有扩展方法'Value'接受'object'类型的第一个参数(你是否缺少using指令或汇编引用?)”< / p>
请注意,这与后期绑定无关。
另一方面,在VB.NET中,以下代码 将在没有Option Strict
的情况下编译:
Dim o As New Object()
Console.WriteLine(o.Value)
但会输出警告:“后期绑定解决方案;可能会发生运行时错误。”
该代码在运行时确实会失败:
“找不到'对象'类型上的公共成员'价值'。”
VB.NET允许编译上面的代码,因为它为方法添加了额外的方法调用,这可以在我们反编译程序时看到:
object o = RuntimeHelpers.GetObjectValue(new object());
Console.Write(RuntimeHelpers.GetObjectValue(NewLateBinding.LateGet(o, null, "Value", new object[0], null, null, null)));
Console.Write(RuntimeHelpers.GetObjectValue(NewLateBinding.LateGet(o, null, "Value", new object[0], null, null, null)));
请注意,LateGet支持VB.NET的后期绑定功能。它检查给定对象是否确实具有Value
属性。如果是,则获取Value属性并将Console.Write的值返回到输出。 Object
本身没有Value
,但其他对象也有,System.Collections.Generic.KeyValuePair<T>
。
LateGet method NewLateBinding class“[e] xecutes后期绑定属性获取或字段访问调用”。我们可以像这样剖析LateGet的参数:
o, // Instance of the object with the property
null, // Type (not used)
"Value", // Name of the property
new object[0], // No arguments
null, // No argument names
null, // No type arguments ('Value' is not generic)
null // N/A; used only on methods with ByRef parameters
RuntimeHelpers.GetObjectValue method 包装给定的对象,因此在这里不那么重要。
在C#中,可以使用以下代码实现后期绑定:
var o=new System.Collections.Generic.KeyValuePair<int,int>(0,1);
Console.WriteLine("{0}",o.GetType().GetProperty("Value").GetValue(o,new object[]{}));
我在这里使用KeyValuePair
因为它包含Value
属性。如果它只是Object
,代码将编译,但在运行时会因NullReferenceException而失败,因为Value
中不存在Object
。代码获取对象的类型,获取与属性“Value”关联的PropertyInfo,并从对象和PropertyInfo获取值。 LateGet
最有可能使用非常相似的技术。
答案 1 :(得分:2)
对象上没有.Value。
当您将Option Strict
转为Off
时,您允许VB.Net动态调用方法和属性。为什么.Value
似乎适合您,不是因为Object具有该属性,而是因为您指定的对象到SelectedItem
具有.Value
属性
试试这个
Option Strict Off
Module Module1
Public Class tst
Public Value As Integer = 5
End Class
Sub Main()
Dim a As Object
a = New tst()
Console.WriteLine(a.Value)
a = New List(Of Integer)()
Console.WriteLine(a.Value)
End Sub
End Module
请注意,第一个写作线写出“5”,但第二个写入异常,因为List<>
没有.Value属性。
答案 2 :(得分:0)
后期绑定意味着子类的方法超过了父类的方法。 (或者,对于属性也可以这样说。)
在这种情况下,我假设SelectedItem是Object的子类的实例,但是ListBox1对它的引用是一个Object实例。这意味着没有后期绑定,将检查Object的Value属性。
因此,您应该尝试将SelectedItem转换为它实际的类型。
(免责声明:我不是一个VB人。我基于错误信息的措辞以及我对继承绑定通常如何工作的理解。)
答案 3 :(得分:0)
.NET中的对象上没有Value属性。
您所看到的是动态对象支持,它允许您在不声明任何内容的情况下创建所需内容的新属性。
您的代码基本上是尝试在SelectedItem上声明一个“Value”对象(当前未初始化)(在Windows窗体中将其视为对象)。由于没有Value属性,因此它认为您要创建一个。
Option Strict On
不允许在未声明的情况下动态创建类型,因此这就是您看到错误的原因。实际上,.NET阻止你在脚下射击,告诉你......不......没有Value属性。这是Option Strict On
为什么这么好的原因的一个很好的例子。
为了说明我的观点,请尝试将代码更改为:
ListBox1.SelectedItem.Supercalifragilisticexpialadocious
你会得到同样的错误。另请阅读 Option Strict Statement (MSDN)中备注下的第三段。