Jak złączyć dwie listy bez tworzenia nowej?

0

Mam w klasie (o nazwie dajmy na to X) dwie listy tego typu:

public List<ClientObjectTester> Clients { get; } = new();
public List<NodeObjectTester> Nodes { get; } = new();

Obiekty w tych listach są w trakcie działania programu dynamicznie dodawane i usuwane. Obie klasy przechowywane w listach Client i Node dzielą ze sobą pewne cechy (implementują ten sam interfejs).
Tworzę teraz nową klasę Y, w której odwołuję się do X w celu dostępu do tych list. Z tym że w klasie Y podział na 2 listy nie ma sensu, chciałbym trzymać zarówno Client jak i Node w jednej liście, ponieważ w klasie Y będę operował tylko na tych współdzielonych przez obie klasy cechach.
Mógłbym zrobić coś tego typu:

var allObjects = Nodes.Concat(Clients).ToList();

Z tym, że w tym przypadku tworzy się nowa lista, ze skopiowanymi referencjami z obu łączonych list. Ja natomiast chciałbym, żeby "złączona" lista była zawsze aktualna. To znaczy, że nawet po złączeniu obu list, jeżeli w liście Nodes pojawi się nowy obiekt, to automatycznie będzie on dostępny w tej nowej, "zbiorczej" liście. Jak coś takiego zrobić?

4

A musi być lista? Może IEnumerable<IObjectTester> wystaczy? Wtedy po prostu to by wystarczyło:

public IEnumerable<IObjectTester> AllObjects => Nodes.Concat(Clients);

Z tymże to podejście nie jest thread-safe i trzeba być tego świadomym. Jeśli to nie wystarczy, to będziemy kombinować dalej ;).

4
iteredi napisał(a):

Chyba nie musi być lista, interesuje mnie tylko wyszukiwanie obiektów po Id. Co do thread-safe to tak, w zasadzie moja aplikacja działa wielowątkowo, pytanie co tu masz konkretnie na myśli. To znaczy: co tu może potencjalnie złego się stać?

Jeśli będziesz w jednym wątku dodawał/usuwał jakiś obiekt z listy Clients lub Nodes, a w tym samym czasie będziesz iterował po AllObjects w innym wątku to dostaniesz wyjątek.

0

Jeżeli używasz interfejsów, to nie lepiej trzymać to w jednej klasie?

class Program
    {
        static void Main(string[] args)
        {
            List<IObjectInterface> objectList = new List<IObjectInterface>();
            objectList.Add(new ClientObjectTester());
            objectList.Add(new ClientObjectTester());
            objectList.Add(new NodeObjectTester());
            objectList.Add(new ClientObjectTester());
            objectList.Add(new NodeObjectTester());
            Console.WriteLine($"ClientObjectTester: {objectList.Count(x => x.GetType() == typeof(ClientObjectTester))}");
            Console.WriteLine($"NodeObjectTester: {objectList.Count(x => x.GetType() == typeof(NodeObjectTester))}");
        }
    }

    public interface IObjectInterface
    {

    }
    public class ClientObjectTester : IObjectInterface
    {

    }
    public class NodeObjectTester : IObjectInterface
    {

    }

Wtedy nie musisz łączyć klas, masz zawsze dostęp do aktualnych danych i za pomocą metody Where() możesz się odwołać do konkretnego typu klasy

1 użytkowników online, w tym zalogowanych: 0, gości: 1