.NET中的(未记录的?)Object.Value是什么?

时间:2011-09-04 22:21:49

标签: .net object

未记录的Object.Value来自.NET?

是方法还是财产?它的目的是什么?

当我写的东西(VB.NET WinForms ...没有尝试过C#)时:

TextBox1.Text = ListBox1.SelectedItem.Value

我收到错误:

Option Strict On disallows late binding.

但是,如果没有Option Strict On,它似乎只是返回对象的值。

Object类上下文中的'Value'的任何文档或解释?

**这个问题与错误无关。这用作上下文的一个例子。它是关于对象类的Value方法/属性是什么? **

4 个答案:

答案 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)中备注下的第三段。