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

C# 为什么ListBox.DisplayMember接受字符串值?,c#,properties,C#,Properties,我目前对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

我目前对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属性,但我们正在将其包装为字符串。为什么我们不简单地执行Results.DisplayMember=Person.FullInfo

编译器如何知道这不是任何旧字符串?以这种方式访问财产有什么好处

为什么我们不简单地执行Results.DisplayMember=Person.FullInfo

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

您可以按以下方式进行设置,这是我的建议:

Results.DataSource = people;
Results.DisplayMember = nameof(person.FullInfo);
为什么我们不简单地执行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);
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);

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

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");
它会打印出来

DisplayName是First,Last,name@domain.com


就像你在问题中的例子一样,我们只将FullInfo作为字符串传递给它。但是ListBox的内部代码足够聪明,可以使用这个字符串作为实际值的映射。看看这个函数:

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");
它会打印出来

DisplayName是First,Last,name@domain.com


就像你在问题中的例子一样,我们只将FullInfo作为字符串传递给它。但是ListBox的内部代码足够聪明,可以使用这个字符串作为实际值的映射

,因为当您设置DisplayMember时,它会查看该对象属性的数据源。。。如果您执行Results.DisplayMember=Person.FullInfo,则它并不表示Person类的实例,而是告诉它查找名为Person.FullInfo的属性。因为设置DisplayMember时,它会查看该对象属性的数据源。。。如果您执行Results.DisplayMember=Person.FullInfo,则它并不表示Person类的实例,而是告诉它查找名为Person.FullInfo的属性。值得注意的是,运算符的名称仅在C 6.0之后可用。值得注意的是,运算符的名称仅在C 6.0之后可用。谢谢。也许我需要一些时间来完全思考,但这很好地澄清了我的问题。谢谢。也许我的头脑需要一段时间来完全思考,但这很好地澄清了我的问题。