C # Настройка состояния свойства элемента

#c# #interface #attributes #tracking

#c# #интерфейс #атрибуты #отслеживание

Вопрос:

Я хотел бы установить свойство с именем «Current», которое дает мне возможность отслеживать, с каким элементом я работаю. Вот мой объем класса:

 namespace ConsoleApp3 {
class Volume : Interface
{
    public string Name { get; set; }
    public Volume()
    {

    }
 }
 

Мой интерфейс называется: «Интерфейс»

 namespace ConsoleApp3{
class Interface
{
    public string Name { get; set; }
    public int Id { get; set; }
    public bool IsCurrent { get; set; }
}
 

И мой класс RootList:

 namespace ConsoleApp3{
class RootList<T> : List<T> where T : Interface, new()
{
    private int _index;
    private int _id;
    public RootList()
    {

    }

    public T First
    {
        get => this[0];
        set => this[0] = value;
    }

    public T Last
    {
        get => this[this.Count - 1];
        set => this[this.Count - 1] = value;
    }
  public T Current
    {
        get
        {
            return this.FirstOrDefault(tTemp => tTemp.IsCurrent == true);
        }
        set
        {
            this.RmCurrent();
            int _index = this.IndexOf(value);
            this[_index].IsCurrent = true;
        }
    }

    public T this[string name]
    {
        get
        {
            return this.FirstOrDefault(tTemp => tTemp.Name == name);
        }
    }
   private void RmCurrent()
    {
        var _iscurrent = this.Where(v => v.IsCurrent = true);
        foreach (var item in _iscurrent)
        {
            item.IsCurrent = false;
        }
    }

    public void Add()
    {
        this.Add(new T());
        this.RmCurrent();
        this.Last.IsCurrent = true;
    }
}
 

}

Я использую свойство «IsCurrent» для отслеживания своих элементов: мой элемент имеет «Текущее» состояние, если свойство «IsCurrent» равно «true». Только один элемент может быть одновременно «текущим». Мой «текущий» метод не работает. Для exmaple:

         VolumeList.Add();
        VolumeList.Last.Name = "test_0";
        VolumeList.Add();
        VolumeList.Last.Name = "test_1";
        VolumeList.Add();
        VolumeList.Last.Name = "test_2";
 

В этом случае мой текущий элемент является последним «test_2».
Если я это сделаю:

            VolumeList.Current = VolumeList[1];
 

У меня есть два текущих элемента VolumeList [0] и VolumeList [1]. Не только VolumeList[1].
Как вы можете видеть, у меня также есть индексатор строк в моем корневом списке, поэтому он должен работать с индексатором int и индексатором string.
У вас есть какие-нибудь идеи?

Большое спасибо.

С наилучшими пожеланиями,

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

1. Мне больше кажется, что задача корневого списка — запомнить текущий элемент, а не сам элемент, чтобы помнить, является ли он текущим. Поиск того, какой элемент является текущим, каждый раз ужасен. Переместите понятие текущего T в корневой список

2. @Caius Jard Это правда! Можете ли вы показать мне, как это сделать?

Ответ №1:

Я бы не стал искать элемент, который является текущим в private void RmCurrent()

Я бы сделал только

 private void RmCurrent()
    {
        foreach (var item in this)
        {
            item.IsCurrent = false;
        }
    }
 

Ответ №2:

Я бы сделал текущий трек корневого списка:

 
public class RootList<T> : List<T> where T : Interface, new()
{
    public T Current { get; private set; }

    public T First
    {
        get => Current = this[0]; 
        set => Current = this[0] = value;
    }

    public T Last
    {
        get => Current = this[this.Count - 1];
        set => Current = this[this.Count - 1] = value;
    }

    public T this[string name]
    {
        //what if there is no such name? what do you want current to be? 
        //if it should not change, break this lambda up using a temp var 
        //that you do not assign to current if it is null

        get => Current = this.FirstOrDefault(tTemp => tTemp.Name == name); 
    }

    public void Add() //careful, the List<T> you inherit from also has an Add(T), and so calling myList.Add(something) it won't set the current item
    {
        Current = new T();
        this.Add(Current);
    }
}
 

Итак, что происходит?

Присваивания в C # возвращают в качестве значения значение, которое было присвоено. Это означает, что это:

 myString = "hello";
 

возвращает «привет». Его можно использовать в другом назначении:

 myString2 = (myString = "hello");
 

Обе строки являются «привет»;

Однострочные лямбды должны быть значением, поэтому это:

 get => Current = this[0]; 
 

Назначает текущий элемент первым элементом в списке, а затем передает первый элемент в списке получателю, который будет возвращен. Это все равно, что сказать:

 get {
  Current = this[0];
  return Current;
}
 

Ваш текущий элемент теперь является первым элементом в списке только потому, что вы получили доступ к первому свойству

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

1. Большое спасибо. Теперь я понимаю, что вы имеете в виду. Первый и последний не будут устанавливать мой текущий, но вы многому меня научили. Мне нужно установить текущий вручную, например: myList.Current = myList[«имя»]; или myList.Current = myList[индекс]. Вы знаете, как это сделать? Спасибо

2. Настройка тока вручную тоже может быть выполнена.. Основная проблема всего вопроса заключается в том, что вы на самом деле никогда не указывали, какие операции влияют на текущий, а какие нет. До сих пор из этого комментария вы говорили «Первый и последний не» и «он устанавливается вручную», но ваше «Добавить» автоматически устанавливает его, поэтому в качестве спецификации того, что необходимо, оно не очень полное / точное . Напишите лучшую спецификацию, и мы сможем помочь больше

3. Конечно, я понимаю. Моим «добавлением» было попробовать то, о чем я думал, но это не важно. Вы показываете мне, как отслеживать его непосредственно из корневого списка, и я многому научился (я не знал, что это возможно). Итак, что мне нужно сейчас, так это вручную установить текущее значение по имени или индексу. Это должно управляться корневым списком, как рекомендовано вами. Первый и последний просто помогают мне ориентироваться в моем списке. Заранее спасибо

4. Вы не можете установить текущее значение, обратившись к индексу int, потому List<T> что у него уже есть public T this[int index] , и вы не можете его переопределить. Вы можете скрыть его, указав свою собственную public new T this[int index] , и ваша версия будет использоваться, если объект используется как корневой список, но не как список (например List<X> x = new RootList<X> , будет использоваться список this[int] , не ваш).. Я думаю, что вместо того, чтобы переходить из List<T>, вам следует написать класс, который реализует IList<T> сам по себе, если вы этого хотите. Он может использовать список внутри и прокси для него

5. Я понял, что вы сказали, но я не уверен, что смогу его закодировать на данный момент. Можно ли просто установить Curren, обратившись к имени строки, которое, конечно, должно быть уникальным? Если нет, можете ли вы показать мне, как закодировать мой собственный класс? (Я знаю, что прошу многого …)