Diskuze: Kolekce ObservableCollection<T>() jako parametr metody
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 19 zpráv z 19.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
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);
}
}
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.
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.
Niečo som našiel, pozri sa na to.
http://stackoverflow.com/…as-parameter
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));
}
Predpokladam, ze to zoradi podla prveho itemu v zozname, takze iny item na zoradenie sa vybrat neda. Je tak?
Bohužel toto řešení v mém případě nezafungovalo.
Kompilátor hlásí (parametr metody je zde
ObservableCollection<Model>()):
error CS0311: Typ Model nelze použít jako parametr typu T v obecném typu nebo metodě SpravceModelu.Serad<T>(System.Collections.ObjectModel.ObservableCollection<T>). Neexistuje žádný implicitní referenční převod z Model na System.IComparable.
Přesto děkuji za radu.
Máš možnost Modelu přidat interface IComparable?
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
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.
Povedzme že mám niekoľko kolekcií (observablecollection), 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?
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.Collections.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();
}
}
}
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.
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();
Bohužel mám kód v práci, takže až v pondělí.
Určitě dám vědět.
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.
Zobrazeno 19 zpráv z 19.