問題:Linq.Expression VB中的GetValue?
我有這個C#程序,它獲取mytable的字段tablename的值。
它工作正常。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace AttachObjectsCS
{
static class Program
{
public class cmytable
{
public string tablename = "test";
}
// http://stackoverflow.com/questions/2616638/access-the-value-of-a-member-expression
private static object GetValue(System.Linq.Expressions.MemberExpression member)
{
System.Linq.Expressions.Expression objectMember = System.Linq.Expressions.Expression.Convert(member, typeof(object));
System.Linq.Expressions.Expression<Func<object>> getterLambda = System.Linq.Expressions.Expression.Lambda<Func<object>>(objectMember);
var getter = getterLambda.Compile();
return getter();
}
public static void AddField<T>(System.Linq.Expressions.Expression<Func<T>> expr, string alias)
{
var body = ((System.Linq.Expressions.MemberExpression)expr.Body);
Console.WriteLine("Name is: {0}", body.Member.Name);
object obj = GetValue(body);
Console.WriteLine("Value is: {0}", obj);
}
/// <summary>
/// Der Haupteinstiegspunkt für die Anwendung.
/// </summary>
[STAThread]
static void Main()
{
if (false)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
cmytable mytable = new cmytable();
AddField(() => mytable.tablename, "te");
Console.WriteLine(Environment.NewLine);
Console.WriteLine(" --- Press any key to continue --- ");
Console.ReadKey();
} // End Sub Main
} // End Class Program
} // End Namespace AttachObjectsCS
現在我需要VB.NET中的相同功能,但它失敗了。
現在,因爲我知道VB.NET和C#並不總是使用相同的linq表達式,所以我並不感到驚訝,因爲我遇到了一個問題。
Module Program
Public Class cmytable
Public tablename As String = "test"
End Class
Public Sub AddField(Of T)(expr As System.Linq.Expressions.Expression(Of Func(Of T)))
Dim body = DirectCast(expr.Body, System.Linq.Expressions.MemberExpression)
Dim strName As String = body.Member.Name
Console.WriteLine("Name is: {0}", strName)
Dim obj As Object = GetValue(body)
Console.WriteLine("Value is: {0}", obj)
End Sub
' http://stackoverflow.com/questions/2616638/access-the-value-of-a-member-expression '
Private Function GetValue(member As System.Linq.Expressions.MemberExpression) As Object
Dim objectMember As System.Linq.Expressions.Expression = System.Linq.Expressions.Expression.Convert(member, GetType(Object))
Dim getterLambda As System.Linq.Expressions.Expression(Of Func(Of Object)) = System.Linq.Expressions.Expression.Lambda(Of Func(Of Object))(objectMember)
Dim getter = getterLambda.Compile()
Return getter()
End Function
Public Sub Main()
Dim mytable As New cmytable
AddField(Function() mytable.tablename)
End Sub
End Module ' Program
問題出在GetValue,問題是我似乎沒有正確的objectMember。
這裏調試輸出表達式:
CS objectMember = {Convert(value(AttachObjectsCS.Program+<>c__DisplayClass0).mytable.tablename)}
VB objectMember = {Convert(value(AttachObjects.Program+_Closure$__1).$VB$Local_mytable.tablename)}
CS getterLambda = {() => Convert(value(AttachObjectsCS.Program+<>c__DisplayClass0).mytable.tablename)}
VB getterLambda = {() => Convert(value(AttachObjects.Program+_Closure$__1).$VB$Local_mytable.tablename)}
我的猜測是,這個問題是$VB$Local_
在$VB$Local_mytable.tablename
現在我想知道我必須要改變這個工作中VB.NET。
任何人都知道/有線索?
編輯:
嗯,這個問題似乎是由「選項推斷關」在項目範圍內的設置引起的。
所以這個問題變成了:如何通過「Option Infer Off」做到這一點?
你VB代碼工作正常,我。 – svick
對我來說也都很好(VS 2008,x64) – Pondidum
@svick:啊,非常有趣。這留下了一個可能的原因。經過測試的假設和發現的權利 - >該問題是由項目範圍設置中的「Option Infer Off」造成的。現在新的問題是我需要做些什麼才能使它與infer = off一起工作。 –