Почему ListBox.DisplayMember принимает строковое значение? - PullRequest
1 голос
/ 22 марта 2019

Я в настоящее время очень плохо знаком с 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?Каковы преимущества доступа к собственности таким образом?

Ответы [ 3 ]

2 голосов
/ 22 марта 2019

Вы имеете дело с отражением здесь.Посмотрите на эту функцию:

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 достаточно умен, чтобы использовать эту строку в качестве карты с фактическим значением

1 голос
/ 22 марта 2019

ListBox использует Reflection для внутреннего отображения данных из своего источника данных. В C # Reflection является мощным механизмом, где вы можете получить доступ к полям объекта, имея только имя поля в виде строки.

Вы можете попробовать отражение с помощью следующего фрагмента:

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);
1 голос
/ 22 марта 2019

Почему мы не просто делаем Results.DisplayMember = Person.FullInfo?

Это установит значение DisplayMember в строку, которую возвращает FullInfo. Значение DisplayMember означает имя свойства, содержащее отображаемое значение.

Вы можете установить его следующим образом, что я и рекомендую:

Results.DataSource = people;
Results.DisplayMember = nameof(person.FullInfo);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...