Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>In .NET, there is no property or method named Value in Object.</p> <p>The way VB.NET handles <code>Object.Value</code> is apparently specific to that language. In C#, for instance, the following code will not even compile:</p> <pre><code> Object o=new Object(); Console.WriteLine(o.Value); </code></pre> <p>with this error:</p> <p>"'object' does not contain a definition for 'Value' and no extension method 'Value' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)"</p> <p>Note that this has nothing to do with late binding.</p> <p>In VB.NET, on the other hand, the following code <em>will</em> compile without <code>Option Strict</code>:</p> <pre><code> Dim o As New Object() Console.WriteLine(o.Value) </code></pre> <p>but will output a warning: "Late bound resolution; runtime errors could occur."</p> <p>That code will indeed fail at runtime:</p> <p>"Public member 'Value' on type 'Object' not found."</p> <p>VB.NET allowed the code above to compile because it adds extra method calls to the method, as can be seen when we decompile the program:</p> <pre><code>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))); </code></pre> <p>Note that LateGet supports the late binding feature of VB.NET. It checks whether the given object really does have a <code>Value</code> property. If it does, it gets the Value property and returns that value for Console.Write to output. <code>Object</code> itself doesn't have <code>Value</code>, but other objects do, such as <code>System.Collections.Generic.KeyValuePair&lt;T&gt;</code>.</p> <p>The <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.compilerservices.newlatebinding.lateget.aspx" rel="nofollow">LateGet method</a> of the <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.compilerservices.newlatebinding.aspx" rel="nofollow">NewLateBinding class</a> "[e]xecutes a late-bound property get or field access call". We can dissect the arguments of LateGet like so:</p> <pre><code>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 </code></pre> <p>The <a href="http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.runtimehelpers.getobjectvalue.aspx" rel="nofollow">RuntimeHelpers.GetObjectValue method</a> boxes the given object, and is thus less relevant here.</p> <p>In C#, late binding can be achieved using code like the following:</p> <pre><code>var o=new System.Collections.Generic.KeyValuePair&lt;int,int&gt;(0,1); Console.WriteLine("{0}",o.GetType().GetProperty("Value").GetValue(o,new object[]{})); </code></pre> <p>I use <code>KeyValuePair</code> here because it contains a <code>Value</code> property. If it were just an <code>Object</code> the code will compile, but will fail at runtime with a NullReferenceException because <code>Value</code> doesn't exist in <code>Object</code>. The code gets the object's type, gets the PropertyInfo associated with the property "Value", and gets the value from the object and the PropertyInfo. <code>LateGet</code> most likely uses a very similar technique.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload