繁体   English   中英

如何在函数内检测变量* name *(不是类型)(为什么?对于自定义ASP.Net数据绑定实现)

[英]How to detect variable *name* (not type) within a function (Why? For a custom ASP.Net databinding implementation)

因此,假设我有以下代码(VB.Net):

Sub Main()
   dim xxx as string = "HELLO WORLD"

   DetectName(xxx)

End Sub

Public Sub (theVariable as string)
   dim output as string = "The Value: {0} was stored in the variable named: {1}."
   debug.writeline(string.format(output, theVariable, What Goes Here????))
End Sub

我想看的输出是:

值:HELLO WORLD存储在名为xxx的变量中。

通过反射可能以某种方式有可能吗? (如果您明确地知道这是不可能的,那也很有用)。

如果您想知道为什么要这样做...我试图找到一种体面的方式为asp.net编写自定义绑定类(用于表单,而不是网格),因为我似乎找不到任何有效的方法足以值得使用它的麻烦。 (注意:我正在使用Webforms,不能使用MVC解决此问题)。

我在考虑提供绑定信息的约定如下:
asp:TextBox id =“ myClassInstanceName.myPropertyName” ...

所以,那么我可以有一个像这样的功能:

Public Sub Bind(webForm as System.Web.UI.Page, bindingObjects as HashTable)
   For each ctl in webForm.flattenedControls that contains "." within ID
      ' Here, which property is set would actually depends on control type
      ' magicGetValue() would find the property class instance within bindingObjects, which is indexed by variable *NAME* (not type), and then return the proper property value via reflection  
      ctl.Text = magicGetValue(ctl.ID, bindingObjects)
   End Sub
End Sub

就我个人而言,我认为这是一种比推荐的asp:FormView,Bind(“”)方法更简单且更强大的语法。 例如:
-如果我想实现将其呈现为只读的功能,则它是对我的基础Bind函数的相当简单的更改。
-如果要使用多个类来填充UI,可以-如果要遍历丰富的域模型,可以:
asp:TextBox id =“ _ Customer.Address.State”

我不喜欢的是:
-依靠反思
-松散输入(不检查编译时间)
-我宁愿将绑定信息存储在ID之外的其他位置,但是不知道它在aspx定义中还有其他地方。 在某些方面,将绑定声明移到后面的代码会更好,但在另一些方面会更糟。

如果有人有任何见解或建议,我将不胜感激!

它绝对不会按照您想要的方式工作,因为局部变量名称在编译后甚至不包含在程序集中。

如果变量是一个类的字段(通过使字段信息而不是实际的数值时,或者当变量被传递的ByRef的)有可能

您无法直接检测到变量的名称,但是可以通过将变量传递给函数时将其包装为匿名类型来解决。

然后,您可以使用反射来询问匿名类型。 由于name inferencing ,类型属性的名称将与原始变量的名称匹配。

Sub Main()
    Dim xxx As String = "HELLO WORLD"
    Dim yyy As Integer = 42
    Dim zzz As DateTime = DateTime.Now

    DetectName(New With { xxx })
    DetectName(New With { yyy })
    DetectName(New With { zzz })

    ' or...
    ' DetectName(New With { xxx, yyy, zzz })
End Sub

Public Sub DetectName(Of T As Class)(test As T)
    Dim piArray As PropertyInfo() = GetType(T).GetProperties()

    Dim pi As PropertyInfo
    For Each pi In piArray
        Dim name As String = pi.Name
        Dim value As Object = pi.GetValue(test, Nothing)

        Dim output As String = _
            "The Value: {0} was stored in the variable named: {1}."
        Debug.WriteLine(String.Format(output, value, name))
    Next
End Sub

并且,为完整起见,这是C#版本:

void Main()
{
    string xxx = "HELLO WORLD";
    int yyy = 42;
    DateTime zzz = DateTime.Now;

    DetectName(new { xxx });
    DetectName(new { yyy });
    DetectName(new { zzz });

    // or..
    // DetectName(new { xxx, yyy, zzz });
}

public void DetectName<T>(T test) where T : class
{
    PropertyInfo[] piArray = typeof(T).GetProperties();

    foreach (PropertyInfo pi in piArray)
    {
        string name = pi.Name;
        object value = pi.GetValue(test, null);

        string output = "The Value: {0} was stored in the variable named: {1}.";
        Debug.WriteLine(string.Format(output, value, name));
    }
}

如果我了解您的要求,则无需完成第一部分中描述的内容即可完成问题第二部分中所说的内容。 由于您可以访问创建的文本框的ID字符串,因此您应该能够通过反射来获取要查找的属性:

PropertyDescriptor keyDescriptor = TypeDescriptor.GetProperties(dataItem).Find(keyPropertyName, false);
Key = keyDescriptor.GetValue(dataItem);

如果您认为这行不通,还可以进一步澄清问题吗?

但是,我同意mihi的观点,即您无法发现方法范围内局部变量的名称。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM