Diskuze: Kolekce ObservableCollec­tion<T>() jako parametr metody

C# .NET .NET (C# a Visual Basic) Kolekce ObservableCollec­tion<T>() jako parametr metody American English version English version

Avatar
Martin Turner:

Ahoj,
řeším jednu drobnost s kolekcemi ObservableCollec­tion<T>().
Rád bych použil pouze jednu metodu zpracovávající několik kolekcí ObservableCollec­tion<T>(), které mají různý typ <T> a nevím, jak si ji jako parametr předat.
Tuší někdo, jak na to?
Děkuji.

 
Odpovědět 5.11.2015 6:37
Avatar
Odpovídá na Martin Turner
Libor Šimo (libcosenior):

Jediné univerzálne metódy som použil na čítanie a uloženie kolekcie.

public T Nacitaj<T>(string Subor)
        where T : new()
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            if (File.Exists(Subor))
            {
                using (StreamReader sr = new StreamReader(Subor))
                {
                    return (T)serializer.Deserialize(sr);
                }
            }
            else
                return new T();
        }

        public void Uloz<T>(T instance, string subor)
        {
            XmlSerializer serializer = new XmlSerializer(instance.GetType());
            using (StreamWriter sw = new StreamWriter(subor))
            {
                serializer.Serialize(sw, instance);
            }
        }
Nahoru Odpovědět 5.11.2015 11:13
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na Libor Šimo (libcosenior)
Martin Turner:

Děkuju za odpověď, určitě mě pomohla.
Jen mám stále ještě problém, má metoda vypadá takto:

private void Serad<T>(T seznam) // T je ObservableCollection<TridaX>
        {
            seznam = new T(seznam.OrderBy(a => a.Varianta));
            if(seznam.Count() > 0)
            {
                VyvolejZmenu("seznam");
            }
            else
                seznam = null;

        }

Toto bohužel nefunguje, netušíš, jak sortování takto přijaté kolekce udělat?
Díky moc.

 
Nahoru Odpovědět 5.11.2015 12:04
Avatar
Odpovídá na Martin Turner
Libor Šimo (libcosenior):

Tiež mám v aplikácii niekoľko kolekcií a chcel som to riešiť univerzálnymi metódami, ale nešlo to, pretože sa vo funkcii odkazujem na konkrétny item kolekcie.
V tvojom prípade "a.Varianta".
Možno to nejak inakšie ide, ale ja som spôsob nenašiel.

Nahoru Odpovědět 5.11.2015 13:15
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Nahoru Odpovědět 5.11.2015 15:03
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Ghst
Člen
Avatar
Ghst:

Vyzkoušej tohle, něco podobného jsem používal na seznam

private void Serad<T> ( ObservableCollection<T> seznam ) where T :IComparable, IEnumerable<T>
{
    if ( seznam.Count == 0 )
        throw new Exception();

    seznam = new ObservableCollection< T >(seznam.OrderBy(a => a));

}
Editováno 5.11.2015 16:15
 
Nahoru Odpovědět 5.11.2015 16:12
Avatar
Odpovídá na Ghst
Libor Šimo (libcosenior):

Predpokladam, ze to zoradi podla prveho itemu v zozname, takze iny item na zoradenie sa vybrat neda. Je tak?

Nahoru Odpovědět 5.11.2015 17:10
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na Ghst
Martin Turner:

Bohužel toto řešení v mém případě nezafungovalo.
Kompilátor hlásí (parametr metody je zde ObservableCollec­tion<Model>()):

error CS0311: Typ Model nelze použít jako parametr typu T v obecném typu nebo metodě SpravceModelu­.Serad<T>(Sys­tem.Collection­s.ObjectModel­.ObservableCo­llection<T>). Neexistuje žádný implicitní referenční převod z Model na System.IComparable.

Přesto děkuji za radu.

 
Nahoru Odpovědět 6.11.2015 7:17
Avatar
Odpovídá na Martin Turner
Luboš Běhounek (Satik):

Máš možnost Modelu přidat interface IComparable?

Nahoru Odpovědět 6.11.2015 7:43
:)
Avatar
Ghst
Člen
Avatar
Odpovídá na Martin Turner
Ghst:

Nelze použít, protože daná třída nemá neimplementované rozhraní IComparable.
Pokud máš možnost ji doimplementovat tak to udělej, v opačném případě by jsi musel naimplementovat comparer Modelu explicitně.

To Libor: seřadí se to podle toho, jak bude naimplementovaný comparátor pro danou třídu <T>, případně lze nějakým způsobem poslat metodu provádějící comparaci

 
Nahoru Odpovědět 6.11.2015 8:20
Avatar
Odpovídá na Ghst
Martin Turner:

Omlouvám se, ale popravdě tomu moc nerozumím.
Do metody vkládám kolekce s různými <T>, znamená to, že v každé třídě reprezentující T musím doplnit implementaci IComparable s metodou CompareTo (předpokládám, že ano)?
A když jedna ze tříd je zděděna, lze metoda CompareTo přepsat (obávám se, že ne)?
Lze to případně řešit jinak?
Snažím se googlit, ale zatím se nezadařilo.
Díky.

 
Nahoru Odpovědět 6.11.2015 8:55
Avatar
Odpovídá na Ghst
Libor Šimo (libcosenior):

Povedzme že mám niekoľko kolekcií (observableco­llection), ktoré majú niekoľko spoločných itemov (dedia z rovnakej triedy) a chcel by som jednu metódu pre všetky kolekcie napr. na zoradenie podľa vybratého itemu .
Mám dve metódy:

public void ZoradOsobyMeno()
        {
            Osoby = new ObservableCollection<Osoba>(Osoby.OrderBy(a => a.Meno));
        }

        public void ZoradMiestnostiMeno()
        {
            Miestnosti = new ObservableCollection<Miestnost>(Miestnosti.OrderBy(a => a.Meno));
        }

Ako by mala vyzerať spoločná metóda?
Môžeš uviesť príklad?

Nahoru Odpovědět 6.11.2015 9:24
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Ghst
Člen
Avatar
Ghst:
where T :IComparable

Znamená, že každý prvek T musí implementovat rozhrají IComparable, nevidím důvod, proč by nešla u potomka metoda CompareTo přepsat.

Případně lze řešit vytvořením comparátoru.

Na msdn si najdi IComparator, IComparable, případně generické verze a jejich použití v System.Collec­tions.Generic­.Sort()

Teoreticky by jsi nepotřeboval ani tebou zminovanou metodu a zavolas na kazdy seznam v okamziku, kdy potrebujes seznam.Sort();
pripadne dosadis pozadovany delagat, pokud se ti nebude chtit implementovat rozhrani?

namespace Pokus
{
    class CompareByNumber : IComparer<TestClass>
    {
        int IComparer<TestClass>.Compare ( TestClass x, TestClass y )
        {
            return ( x.Number - y.Number );
        }
    }

    class CompareByString : IComparer<TestClass>
    {
        int IComparer<TestClass>.Compare ( TestClass x, TestClass y )
        {
            return ( x.Text.Length - y.Text.Length );
        }
    }

    class TestClass : IComparable<TestClass>
    {
        public int Number { get; private set; }
        public string Text { get; private set; }

        public TestClass ( int c, string t)
        {
            Number = c;
            Text = t;
        }
        public int CompareTo ( TestClass other )
        {
            return (this.Number - other.Number);
        }
    }
}

namespace Pokus
{
    class Program
    {
        static void Main ( string [ ] args )
        {
            List<TestClass> pokus = new List<TestClass>();
            pokus.Add(new TestClass(5, "Adsfasdfztztf"));
            pokus.Add(new TestClass(8, "BC"));
            pokus.Add(new TestClass(1, "SDDFC"));
            pokus.Add(new TestClass(9, "fdsfD"));
            pokus.Add(new TestClass(4, "Esafsdaxcx"));
            pokus.Add(new TestClass(2, "yxcveF"));

            foreach ( TestClass element in pokus )
            {
                Console.WriteLine(String.Format("{0} - {1}", element.Number, element.Text));
            }
            //implicitne implementovany comparator
            pokus.Sort();
            //explicitni comparatory
            //pokus.Sort(new CompareByNumber());
            //pokus.Sort(new CompareByString());
            Console.WriteLine("Serazena");
            foreach ( TestClass element in pokus )
            {
                Console.WriteLine(String.Format("{0} - {1}", element.Number, element.Text));
            }
            Console.ReadKey();
        }
    }
}
Editováno 6.11.2015 12:29
 
Nahoru Odpovědět 6.11.2015 12:27
Avatar
Odpovídá na Ghst
Martin Turner:

Zkusil jsem podle tvého návrhu toto:

private void Serad<T> ( ObservableCollection<T> seznam ) where T : IComparable
{
    if ( seznam.Count == 0 )
        throw new Exception();

    seznam = new ObservableCollection< T >(seznam.OrderBy(a => a));

}

a do třídy T jsem implementoval ToCompare, kde řeším jak a podle čeho má být kolekce setříděná, a funguje to.

Děkuju všem za připomínky a pomoc.

 
Nahoru Odpovědět 6.11.2015 13:51
Avatar
Ghst
Člen
Avatar
Odpovídá na Martin Turner
Ghst:

Ukázal by jsi mi kód pro zajímavost? mě se to s použitím OrderBy(a=>a) nepodařilo, pouze se Sort()... Respektive OrderBy nezměnilo pořadí prvků v kolekci, to jsem dosál až sortem, který modifikuje původni kolekci, takze nemusis pouzit

 seznam = new ObservableCollection< T >(seznam.OrderBy(a => a));
//ale
seznam.Sort();
Editováno 6.11.2015 15:00
 
Nahoru Odpovědět 6.11.2015 14:59
Avatar
Odpovídá na Ghst
Martin Turner:

Bohužel mám kód v práci, takže až v pondělí. :-)
Určitě dám vědět.

 
Nahoru Odpovědět 6.11.2015 16:10
Avatar
Odpovídá na Ghst
Martin Turner:

Pro přepis původní kolece používám místo void návratový typ:

private ObservableCollection<T> Serad<T> ( ObservableCollection<T> seznam ) where T : IComparable
{
    if ( seznam.Count == 0 )
        throw new Exception();

    seznam = new ObservableCollection< T >(seznam.OrderBy(a => a));
    return seznam;
}

V dané třídě T mám pak metodu:

public int CompareTo(object obj)
        {
            if(obj == null)
                return 1;
            Model novyModel = obj as Model;
            if (novyModel != null)
            {
                return this.Varianta.CompareTo(novyModel.Varianta);
            }
            else
                throw new ArgumentException("Objekt neni Model");
        }

Kdybys měl jakýkoliv dotaz, dej vědět.
Díky.

 
Nahoru Odpovědět 9.11.2015 15:04
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 19 zpráv z 19.