#c# #properties
#c# #свойства
Вопрос:
В настоящее время я новичок в 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
? Каковы преимущества доступа к свойству таким образом?
Комментарии:
1. Потому что, когда вы устанавливаете
DisplayMember
, оно просматриваетDataSource
для этого свойства объекта… Если вы это сделаетеResults.DisplayMember = Person.FullInfo
, это не будет представлять экземпляр класса person, скорее это будет указание ему искать свойство с именемPerson.FullInfo
.
Ответ №1:
Здесь вы имеете дело с отражением. Взгляните на эту функцию:
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 является первым, последним, (name@domain.com )
Точно так же, как в вашем примере в вопросе, мы передаем "FullInfo"
в него только как строку. Но внутренний код ListBox
достаточно умен, чтобы использовать эту строку в качестве сопоставления с фактическим значением
Комментарии:
1. Спасибо. Возможно, мне потребуется некоторое время, чтобы полностью охватить отражение, но это прекрасно проясняет мой вопрос.
Ответ №2:
Почему мы просто не создаем результаты.DisplayMember = Person.FullInfo?
Это установило бы значение DisplayMember
в строку, которую возвращает FullInfo. Значение DisplayMember
должно быть именем свойства, содержащего отображаемое значение.
Вы могли бы установить его следующим образом, что я и рекомендую:
Results.DataSource = people;
Results.DisplayMember = nameof(person.FullInfo);
Комментарии:
1. Стоит отметить, что
nameof
оператор доступен только начиная с C # 6.0.
Ответ №3:
ListBox использует отражение внутри себя при отображении данных из своего источника данных. В C # отражение — это мощный механизм, с помощью которого вы можете получить доступ к полям i.e объекта, имея только имя поля в виде строки.
Вы можете попробовать отражение со следующим фрагментом:
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);