Определите, к какому свойству принадлежит коллекция

#c# #observablecollection #.net-4.8

#c# #observablecollection #.net-4.8

Вопрос:

Я создал небольшой тест. Как я могу узнать, возможно, используя отражение, когда внутри void Add(T t) какому свойству принадлежит коллекция? Я хочу программно получить имя свойства ‘MyVotes’, возможно, через PropertyInfo.

 void Main()
{
    var myClass = new MyClass();
    myClass.MyVotes.Add("Democratic");
    myClass.MyVotes.Add("Republican");
    myClass.MyVotes.Add("Independent");
}

public class MyClass
{
    public MyCollection<string> MyVotes { get; }
    
    public MyClass()
    {
        MyVotes = new MyCollection<string>();
    }
}

public class MyCollection<T> : ObservableCollection<T>
{
    public new void Add(T t)
    {
        base.Add(t);
        
        // how do I find out what property name this collection is within MyClass object?
    }
}
 

Комментарии:

1. Его нет. Что, если вы вызовете это для переменной? Вызывающий объект не должен заботиться о том, какие значения для его параметров вызываются. Почему вы хотите знать?

2. Это выглядит немного некрасиво и очень плохая идея. Чего вы пытаетесь достичь? Должно быть более подходящее решение.

3. Я пытаюсь упростить обработчик сбора, посредством которого при появлении записи он вызывает AutoMapper и сбрасывает ее в другой список. Я могу обойти это, добавив в класс больше типов времени компиляции, просто подумал, что может быть более простой подход.

4. Это ObservableCollection, верно? Так что соблюдайте это. Если вам нужно, чтобы MyClass что-то делал при добавлении элемента в коллекцию, просто попросите его обработать событие CollectionChanged коллекции. Самой коллекции не нужно ничего знать о том, где она используется.

Ответ №1:

Похоже, у вас есть полный контроль над источником, поэтому я бы предложил просто передать необходимую информацию в коллекцию через параметр конструктора.

 public class MyClass
{
    public MyCollection<string> MyVotes { get; }
    
    public MyClass()
    {
        MyVotes = new MyCollection<string>(nameof(MyVotes));
    }
}

public class MyCollection<T> : ObservableCollection<T>
{
    private readonly string _propertyName;

    public MyCollection(string propertyName) => _propertyName = propertyName

    public new void Add(T t)
    {
        base.Add(t);
        
        Console.WriteLine($"Using {_propertyName}");
    }
}
 

Я использовал nameof здесь, чтобы сделать его рефакторинг безопасным. Если вам нужно передать больше, чем просто имя свойства, например, the PropertyInfo , вы можете сделать это вместо этого.