为什么ListBox.DisplayMember接受字符串值



我目前对C#很陌生,我的大部分知识来自Java和Python。话虽如此,我目前有以下代码:

public class Person
{
    public int Person_ID { get; set; }
    public String First_Name { get; set; }
    public String Last_Name { get; set; }
    public String EmailAddress { get; set; }

    public String FullInfo
    {
        get
        {
            // Matthew Arnold (mtthwrnld@gmail.com)
            return $"{First_Name}, {Last_Name}, ({EmailAddress})";
        }
    }
}

此处使用的"FullInfo"属性:

private void button1_Click(object sender, EventArgs e)
{
    //'Results' is a ListBox
    //'people' is a List of type Person
    DataAccess db = new DataAccess();
    people = db.getPeople(lastNameText.Text);
    Results.DataSource = people;
    Results.DisplayMember = "FullInfo";
}

我的问题明确地涉及这一行:Results.DisplayMember = "FullInfo";

这个作业实际上是如何运作的?我们正在将DisplayMember设置为 FullInfo 属性,但我们将其包装在一个 String 中。我们为什么不简单地做Results.DisplayMember = Person.FullInfo

编译器怎么知道这不是任何旧String?以这种方式进入房产有什么好处?

你在这里处理的是反思。看看这个函数:

public static void GetDisplayName(object anyType, string displayName)
{
    var type = anyType.GetType();
    var displayProperty = type.GetProperty(displayName);
    if (displayProperty != null)
    {
        Console.WriteLine($"DisplayName is {displayProperty.GetValue(anyType)}");
        return;
    }
    var displayFiled = type.GetField(displayName);
    if (displayFiled != null)
    {
        Console.WriteLine($"DisplayName is {displayFiled.GetValue(anyType)}");
        return;
    }
    // can't find displayName
    Console.WriteLine($"DisplayName is {type.Name}");
}

如果你这样称呼它

var person = new Person
{
    Person_ID = 42,
    First_Name = "First",
    Last_Name = "Last",
    EmailAddress = "name@domain.com"
};
GetDisplayName(person, "FullInfo");

它将打印

显示名称是第一个、最后一个、(name@domain.com(

就像您在问题中的示例一样,我们仅将"FullInfo"作为字符串传递到其中。但是内部代码ListBox足够聪明,可以将这个字符串用作实际值的映射

为什么我们不简单地做 Results.DisplayMember = Person.FullInfo?

这会将 DisplayMember 的值设置为 FullInfo 返回的字符串。DisplayMember 的值是保存要显示的值的属性的名称。

您可以按以下方式设置它,这是我推荐的:

Results.DataSource = people;
Results.DisplayMember = nameof(person.FullInfo);

ListBox 在内部使用反射,同时显示其数据源中的数据。在 C# 中,反射是一种强大的机制,您可以通过仅将字段名称作为字符串来访问对象字段。

您可以尝试使用以下代码片段进行反射:

var person = new Person{First_Name = "FirstName", Last_Name="LastName", Person_ID=12, EmailAddress="email@email.com"};
var fullInfo = person.GetType().GetProperty("FullInfo").GetValue(person, null);

最新更新