2x Dell UP2716D | R9 7950X | 128GB RAM | 980 Pro 2TB x2 | RTX2070 Super
.oisyn: Windows is net zo slecht in commandline als Linux in GUI
Als je een methode hebt die T als param heeft kan dat niet. Want dan zou je ineens Bar instances kunnen meegeven als param van die method, terwijl die instance niet alleen met ZBar kan werken.F.West98 schreef op zondag 19 oktober 2014 @ 16:28:
...
Waarom kan je dit niet doen:
C#:
1 2 3 4 5 6 7 8 public class Foo<T> where T : Bar {} public class Bar {} public class ZBar : Bar {}; /**/ Foo<ZBar> zbarFoo = new Foo<ZBar>(); var barFoo = (Foo<Bar>) zbarFoo; // dit kan niet
Je zou toch zeggen dat je dat wel kan casten aangezien het een parent is en je dus prima weet dat een cast kan.....
Op het moment dat Foo geen methods bevat met een param T, kun je de generic definieren als Foo<out T>, dan mag het wel, maar mag je T ook alleen als return gebruiken (en als out param? maar dat weet ik niet 100% zeker).
Omdat het niet altijd opgaat:F.West98 schreef op zondag 19 oktober 2014 @ 16:28:
...
Waarom kan je dit niet doen:
C#:
1 2 3 4 5 6 7 8 public class Foo<T> where T : Bar {} public class Bar {} public class ZBar : Bar {}; /**/ Foo<ZBar> zbarFoo = new Foo<ZBar>(); var barFoo = (Foo<Bar>) zbarFoo; // dit kan niet
Je zou toch zeggen dat je dat wel kan casten aangezien het een parent is en je dus prima weet dat een cast kan.....
1
2
3
| List<Dog> dogs = new List<Dog>(); var animals = (List<Animal>) dogs; animals.Add(new Cat()); // ? |
Ik doe geen C#, maar volgens TFM kan dat wel als je die parameter expliciet als covariant declareert.F.West98 schreef op zondag 19 oktober 2014 @ 16:28:
Waarom kan je dit niet doen: [knip]
Maar dat moet dan wel in een interface.Soultaker schreef op zondag 19 oktober 2014 @ 17:04:
[...]
Ik doe geen C#, maar volgens TFM kan dat wel als je die parameter expliciet als covariant declareert.
Ipsa Scientia Potestas Est
NNID: ShinNoNoir
Covariance en Contravariance in generics. Zat over te vinden. Het was voor .net 4.0 nog stricter. In 4.0 kan het wel alleen zijn er nog steeds beperkingen.F.West98 schreef op zondag 19 oktober 2014 @ 16:28:
...
Waarom kan je dit niet doen:
C#:
1 2 3 4 5 6 7 8 public class Foo<T> where T : Bar {} public class Bar {} public class ZBar : Bar {}; /**/ Foo<ZBar> zbarFoo = new Foo<ZBar>(); var barFoo = (Foo<Bar>) zbarFoo; // dit kan niet
Je zou toch zeggen dat je dat wel kan casten aangezien het een parent is en je dus prima weet dat een cast kan.....
Maar er is genoeg over te vinden als je zoekt op bovenstaande termen.
En de oplossing bleek simpel (bedankt voor de tips!), een ICovariant interface met out R, die implementeren in mijn Collection-class, en nu op één plek nog een beetje een dirty cast (van ICovariant<...> naar ...Collection<....>, maar die Collection is de enige class die ICovariant implementeert)
[ Voor 97% gewijzigd door F.West98 op 19-10-2014 23:43 ]
2x Dell UP2716D | R9 7950X | 128GB RAM | 980 Pro 2TB x2 | RTX2070 Super
.oisyn: Windows is net zo slecht in commandline als Linux in GUI
Waarom heb je nog steeds een cast nodig? Zou je dan niet gewoon meer methoden in je interface moeten opnemen?F.West98 schreef op zondag 19 oktober 2014 @ 23:42:
En de oplossing bleek simpel (bedankt voor de tips!), een ICovariant interface met out R, die implementeren in mijn Collection-class, en nu op één plek nog een beetje een dirty cast (van ICovariant<...> naar ...Collection<....>, maar die Collection is de enige class die ICovariant implementeert)
Ipsa Scientia Potestas Est
NNID: ShinNoNoir
[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]
Omdat eh... de code een beetje apart is opgezet:RayNbow schreef op maandag 20 oktober 2014 @ 06:08:
[...]
Waarom heb je nog steeds een cast nodig? Zou je dan niet gewoon meer methoden in je interface moeten opnemen?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| internal interface ICovariant<out R> {} public class SomeCollection<T> : ICollection<T>, ICovariant<T> where T : SomeObject { private readonly List<T> items = new List<T>(); public void Remove(T item) { item.TryRemoveFromCollection(this); // Yeah, right } internal void RemoveInternal(T item) { items.Remove(item); } /* Meer remove/copy/add functies */ } public class SomeObject { private List<ICovariant<SomeObject>> collections = new List<ICovariant<SomeObject>>(); internal void TryRemoveFromCollection<T>(SomeCollection<T> collection) where T : SomeObject { // Iets met locks collections.Remove(collection); // Hiervoor had ik dus de Covariant nodig (toch?) collection.RemoveInternal((T) this); } // So far, so good. Dan iets met state management enzo, en op het moment dat SomeObject verwijderd kan worden: internal void TryRemoveFromAllCollections() { // Weer locks foreach(var collection in collections) ((SomeCollection<SomeObject>) collection).RemoveInternal(this); // anders kan je die method niet bereiken. Die method valt niet te definiëren in de ICovariant, (want R herbruiken kan niet) collections = null; } } |
Die opzet met de class zichzelf laten toevoegen is btw niet mijn idee, vraag maar aan MS waarom ze dat zo doen
(en sorry voor de enorme hoeveelheid code)
2x Dell UP2716D | R9 7950X | 128GB RAM | 980 Pro 2TB x2 | RTX2070 Super
.oisyn: Windows is net zo slecht in commandline als Linux in GUI
Hoe wil je SomeObject en SomeCollection<T> precies gebruiken?F.West98 schreef op maandag 20 oktober 2014 @ 17:01:
[...]
Omdat eh... de code een beetje apart is opgezet:
C#:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 internal interface ICovariant<out R> {} public class SomeCollection<T> : ICollection<T>, ICovariant<T> where T : SomeObject { private readonly List<T> items = new List<T>(); public void Remove(T item) { item.TryRemoveFromCollection(this); // Yeah, right } internal void RemoveInternal(T item) { items.Remove(item); } /* Meer remove/copy/add functies */ } public class SomeObject { private List<ICovariant<SomeObject>> collections = new List<ICovariant<SomeObject>>(); internal void TryRemoveFromCollection<T>(SomeCollection<T> collection) where T : SomeObject { // Iets met locks collections.Remove(collection); // Hiervoor had ik dus de Covariant nodig (toch?) collection.RemoveInternal((T) this); } // So far, so good. Dan iets met state management enzo, en op het moment dat SomeObject verwijderd kan worden: internal void TryRemoveFromAllCollections() { // Weer locks foreach(var collection in collections) ((SomeCollection<SomeObject>) collection).RemoveInternal(this); // anders kan je die method niet bereiken. Die method valt niet te definiëren in de ICovariant, (want R herbruiken kan niet) collections = null; } }
Die opzet met de class zichzelf laten toevoegen is btw niet mijn idee, vraag maar aan MS waarom ze dat zo doen
(en sorry voor de enorme hoeveelheid code)
Ipsa Scientia Potestas Est
NNID: ShinNoNoir
http://blogs.msdn.com/b/y...ebapi-and-websockets.aspx (codevoorbeeld)
2x Dell UP2716D | R9 7950X | 128GB RAM | 980 Pro 2TB x2 | RTX2070 Super
.oisyn: Windows is net zo slecht in commandline als Linux in GUI
ARGH, leuke foutmelding: 'some dependencies were not satisfied.' Ja uhh, welke dan? man man man
[ Voor 5% gewijzigd door HMS op 20-10-2014 18:41 ]
Maar gebruik je SomeCollection<T> ook voor verschillende T's of is T altijd gelijk aan SomeObject?F.West98 schreef op maandag 20 oktober 2014 @ 18:14:
SomeObject is een WebSocketHandler (met verder functies om dingen over de verbinding te sturen) en die moet je extenden om je eigen functionaliteit te bieden. De Collection wordt static gebruikt om de connections te behouden.
Ipsa Scientia Potestas Est
NNID: ShinNoNoir
T is atm enkel nog gelijk aan een derived class van SomeObject, maar misschien ga ik later nog een derived class maken (daarom wou ik die T in de eerste plaats, voordat ik de <T> had toegevoegd ging hij ervan uit dat alles SomeObject was)RayNbow schreef op maandag 20 oktober 2014 @ 19:03:
[...]
Maar gebruik je SomeCollection<T> ook voor verschillende T's of is T altijd gelijk aan SomeObject?
2x Dell UP2716D | R9 7950X | 128GB RAM | 980 Pro 2TB x2 | RTX2070 Super
.oisyn: Windows is net zo slecht in commandline als Linux in GUI
Waarom gebruik je niet een niet-generic versie van ICollection<T>, namelijk IList?F.West98 schreef op maandag 20 oktober 2014 @ 19:35:
[...]
T is atm enkel nog gelijk aan een derived class van SomeObject, maar misschien ga ik later nog een derived class maken (daarom wou ik die T in de eerste plaats, voordat ik de <T> had toegevoegd ging hij ervan uit dat alles SomeObject was)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| public class SomeCollection<T>: ICollection<T>, IList where T: SomeObject { private readonly List<T> _items = new List<T>(); public bool Remove(T item) { return item.RemoveFromCollection(this); } void IList.Remove(object item) { _items.Remove((T) item); } // meer methods } public class SomeObject { private readonly List<IList> _collections = new List<IList>(); internal bool RemoveFromCollection(IList collection) { collection.Remove(this); return _collections.Remove(collection); } } |
.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?
2) RemoveInternal heeft ook nog wat extra parameters die ik hier weggelaten heb
En het werkte
2x Dell UP2716D | R9 7950X | 128GB RAM | 980 Pro 2TB x2 | RTX2070 Super
.oisyn: Windows is net zo slecht in commandline als Linux in GUI
Het probleem van je code is dat het niet type-safe is. Het staat het volgende toe:F.West98 schreef op maandag 20 oktober 2014 @ 19:35:
[...]
T is atm enkel nog gelijk aan een derived class van SomeObject, maar misschien ga ik later nog een derived class maken (daarom wou ik die T in de eerste plaats, voordat ik de <T> had toegevoegd ging hij ervan uit dat alles SomeObject was)
1
2
3
| var xs = new SomeCollection<DerivedObject>(); var x = new SomeObject(); x.TryRemoveFromCollection(xs); // InvalidCastException |
Ipsa Scientia Potestas Est
NNID: ShinNoNoir
Ook is die ene cast die gebruikt wordt in TryRemoveFromAllCollections, die zelfs enkel wordt aangeroepen VANUIT SomeObject op het moment dat 'ie 'af' is.
Maar ok, gaat misschien een beetje offtopic
[ Voor 41% gewijzigd door F.West98 op 20-10-2014 23:21 ]
2x Dell UP2716D | R9 7950X | 128GB RAM | 980 Pro 2TB x2 | RTX2070 Super
.oisyn: Windows is net zo slecht in commandline als Linux in GUI