Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Covariance sa IS operatorom - Kako resiti ovo?

[es] :: .NET :: Covariance sa IS operatorom - Kako resiti ovo?

[ Pregleda: 1383 | Odgovora: 8 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Boris B.
Ljubljana

Član broj: 213615
Poruke: 286
*.zaslon-telecom.si.



+14 Profil

icon Covariance sa IS operatorom - Kako resiti ovo?08.12.2010. u 15:50 - pre 162 meseci
Imam objekt deklarisan prosto kao npr. object Datasource. U designtime-u nemam pojma sta ce taj datasource biti, moze da bude obican object, moze da bude IEnumerable<T> a moze da bude i EntityCollection<T>.

Potrebno mi je:
Code (csharp):

if (Datasource is EntityCollection<T>)
   ((EntityCollection<T>)Datasource).Load(...)
 


Problem je u tome sto ako ga napisem tako onda moram da deklarisem <T> u potpisu metoda ili u klasi, a onda moram da propagiram <T> svuda gde se pomenuti metod (ili klasa) koristi, sto nema smisla jer ne znam unapred <T> koga mozda i nema u slucaju da Datasource is object.

Ako ga probam "kovariantno" kao
Code (csharp):

if (Datasource is EntityCollection<object>)
   ((EntityCollection<object>)Datasource).Load(...)
 
.
...onda nikada ne prodje if proveru, jer nijedan EntityCollection<T> is EntityCollection<object>, osim kad typeof(T) == typeof(object), sto je u praksi nikada.
if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
 
Odgovor na temu

mmix
Miljan Mitrović
Profesorkin muz
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6042



+4631 Profil

icon Re: Covariance sa IS operatorom - Kako resiti ovo?08.12.2010. u 16:06 - pre 162 meseci
Hmm, pa sve i da mozes da proveris kako bi ga bas castovao u Generic<T>?

dynamic + refleksija?


Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan, sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv… - Z.Đinđić
 
Odgovor na temu

Boris B.
Ljubljana

Član broj: 213615
Poruke: 286
*.zaslon-telecom.si.



+14 Profil

icon Re: Covariance sa IS operatorom - Kako resiti ovo?09.12.2010. u 08:33 - pre 162 meseci
Pa proveru pretpostavljam da bi mogao preko classname-a, if StartsWith("EntiyCollection") then profit!.

Dynamic sa druge strane ima jednu jaaaako nezgodnu i nedokumentovanu osobinu. Naime kad imas neki objekat kao dynamic svi dinamicki pozivi metoda ili property-ja rade doklegod su ti metodi i property-ji deklarisani u istom asembliju kao i sama klasa. Ako imas neki override u descendantu koji je u drugom asembliju onda virtualni pozivi nastali u prvom nece videti override iz drugog. Tradicionalan nacin (GetProperty/MethodInfo) nema to ogranicenje. Ovo sam nazalost otkrio na tezi nacin.
if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
 
Odgovor na temu

mmix
Miljan Mitrović
Profesorkin muz
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6042



+4631 Profil

icon Re: Covariance sa IS operatorom - Kako resiti ovo?09.12.2010. u 08:45 - pre 162 meseci
Cek bre, override-ovi bi morali da rade, ono sto ne radi sigurno su extensions (koji su u stvari u CLRu staticki pozivi koje kompajler "prevarom" dozvoljava kao instance pozive). Medjutim etension metod bi trebao da mozes da pozoves direktno.


A sto se tice EntiyCollection, Type bi morao da ima njegovo ime bez generic parametara, generici se definisu kao atributi Type tipa.

Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan, sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv… - Z.Đinđić
 
Odgovor na temu

Boris B.
Ljubljana

Član broj: 213615
Poruke: 286
*.zaslon-telecom.si.



+14 Profil

icon Re: Covariance sa IS operatorom - Kako resiti ovo?09.12.2010. u 09:19 - pre 162 meseci
Ma ne rade veruj mi. Evo ti konkretan primer:

Osnovni assembly:
- Imam svoju baznu klasu EntityWrapper<T> i virtualni metod Validate().
- Klasa DataManager ima metod ValidateEntity(EntityObject entity).
- Taj ValidateEntity mora da pozove EntityWrapper<typeof(entity)>.Validate(). Najpre mora da nadje wrapper, instancira ga i pozove Validate. Zbog onog <T> ne mogu da staticki zovem Validate jer ne znam T unapred.

Aplikativni assembly:
- Imam klasu Osoba: EntityObject i wrapper OsobaWrapper: EntityWrapper<Osoba>
- Klasa OsobaWrapper override-uje metod Validate i radi validaciju entiteta.


E sad, kad u osnovnom asembliju u DataManager.ValidateEntity napisem:
Code (csharp):

  dynamic wrapper;
  // Nadjem odgovarajuci wrapper preko mog atributa i instanciram ga sa Activatorom. Onda zovem:
  wrapper.Validate(entity);
 


E ovde taj Validate ne radi, iako wrapper referencira pravu instancu !
Ako napisem ovako onda radi:
Code (csharp):

   // Nadjem wrapper preko atributa
   Type wt = (
               from wrapperType in
               (
                   from assembly in AppDomain.CurrentDomain.GetAssemblies()
                   from type in assembly.GetTypes()
                   where type.IsDefined(typeof (EntityWrapperAttribute), false)
                   select type
               )
               from attribute in wrapperType.GetCustomAttributes(false)
               where ((EntityWrapperAttribute) attribute).EntityType.Equals(entity.GetType())
               select wrapperType
            ).FirstOrDefault();

   // Instanciram ga
   var instance = Activator.CreateInstance(wt, Entities, this);

   // Dinamicki zovem Validate
   return wt.GetMethod("Validate").Invoke(instance, new object[] { entity });
 



Ocigledno dynamic ne radi za override u drugom asembliju.
if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
 
Odgovor na temu

mmix
Miljan Mitrović
Profesorkin muz
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6042



+4631 Profil

icon Re: Covariance sa IS operatorom - Kako resiti ovo?09.12.2010. u 10:10 - pre 162 meseci
Ajd probacu za pola sata, ali ne bi smelo da ne radi, sa stanovista objekata ne postoji cross-assembly bariera, sve je to deo istog domena. Da ne radi cross-assembly ne bi ti radila skoro nijedna klasa iz frameworka jer vecina instanci end klasa imaju "mesovite" virtuelne tabele.


Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan, sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv… - Z.Đinđić
 
Odgovor na temu

mmix
Miljan Mitrović
Profesorkin muz
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6042



+4631 Profil

icon Re: Covariance sa IS operatorom - Kako resiti ovo?09.12.2010. u 13:26 - pre 162 meseci
OPk, problem nije do asemblija, problem je u runtime resolvingu, tj isti onaj problem koji si probao da zaobidjes u compile time-u

Kad kreiras instancu wrappera njegov potpis Validate metoda je

EntityWrapper<Osoba>.Validate(Osoba)
Greska je jasna: The best overloaded method match for 'MyCoreAssembly.EntityWrapper<SampleDynamicGen.Osoba>.Validate(SampleDynamicGen.Osoba)' has some invalid arguments

dynamic ne radi overload rezoluciju po runtime tipu parametra ako parametar sam nije dynamic, a tebi nije, definisan je kao EntityObject. E sad dal su mogli da odu jos taj jedan korak napred, to je vec za diskusiju jer je to dalji pad performansi i dodatna dimenzija pretrazivanja overloada, u principu retki su problemi kao tvoj da ne znas T pa ne mozes da castujes objekat. Resenje za dynamic je dynamic-full-on , castuj parametar u dynamic i nateraj resolver da uradi i taj matching (isto sam ti u primeru dao i kako da lociras wrapper bez atributa)

Code (csharp):

            // bez atributa
            // Nadjem wrapper preko atributa
            Type wt = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
                       from type in assembly.GetTypes().Where(t => t.BaseType!= null && t.BaseType.IsGenericType)
                       where (type.BaseType.GetGenericTypeDefinition() == typeof(EntityWrapper<>)) && (type.BaseType.GetGenericArguments()[0] == entity.GetType())
                       select type).FirstOrDefault();

            // Instanciram ga
            dynamic instance = Activator.CreateInstance(wt);
            instance.Validate((dynamic)entity);
 




A ono drugo sto sam hteo da te pitam, sto ne ubacis factory patern za wrapper u EntityObject? Imas u solutionu, ali onda se na kraju datamanageru svodi na

Code (csharp):

        public void ValidateEntityOldSchool(EntityObject entity)
        {
            entity.GetWrapper().Validate(entity);
        }
 


mislim da ti generici ne trebaju uopste ovde.
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan, sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv… - Z.Đinđić
Prikačeni fajlovi
 
Odgovor na temu

Boris B.
Ljubljana

Član broj: 213615
Poruke: 286
*.zaslon-telecom.si.



+14 Profil

icon Re: Covariance sa IS operatorom - Kako resiti ovo?09.12.2010. u 14:12 - pre 162 meseci
Hvala puno za odgovor, mada mi i dalje nije jasno sta se tu desilo:

>EntityWrapper<Osoba>.Validate(Osoba)
>Greska je jasna: The best overloaded method match for 'MyCoreAssembly.EntityWrapper<SampleDynamicGen.Osoba>.Validate(SampleDynamicGen.Osoba)' has some invalid arguments
I dalje mi nije mi jasno gde je greska.
Bazni metod je EntityWrapper<T>.Validate(T entity). Samim tim izvedeni je EntityWrapper<Osoba>.Validate(Osoba entity). Zahvaljujuci templatingu to je isto kao da pise EntityWrapperOsoba.Validate(Osoba entity). Ako imam instancu EntityWrapperOsoba u dinamickoj referenci dynamic r i pozovem r.Validate(Osoba o), ako o jeste osoba (a jeste) onda nema razloga za pomenutu gresku. Procitacu par puta tvoj post pa ce mi valjda biti jasno

EDIT:
Aha sad mi je jasno, on trazi OsobaWrapper.Validate(EntityObject osoba) i ne naravno ne moze da ga nadje. Hvala jos jednom

Sto se tice dobijanja wrapera bez atributa priznajem da nisam znao da se informacije o generickim tipovima propagiraju u runtime i da se mogu dobiti reflectionom, mislio sam da je to samo templating engine koji radi search&replace pred kompajliranjem.

Sto se predloga za factory pattern tice ne mogu da ga implementiram jer EntityObject nije moja klasa kao u tvom primeru, nego je System.Data.Objects.DataClasses.EntityObject i kada importujem bazu u model svi entiteti (npr. Osoba) nasledjuju taj EntityObject. EF4 podrzava POCO, ali je to dosta vise posla i zaboravi na GUI model editor. Upravo zbog toga sam i pravio te wrappere, inace bi Validate bio metod klase EntityObject. Wrapperi pored Validate imaju i New, Query i Delete, a te operacije su vezane na ObjectContext i zato su u DataManageru, jer mi Datamanager enkapsulira i kontekst i UnitOfWork. Na ovaj nacin je kontekst i sve ostalo data-aware odvojeno u svom assembliju, i ostatak programa (GUI, WebPage...) radi samo sa objektima.

[Ovu poruku je menjao Boris B. dana 09.12.2010. u 15:35 GMT+1]

[Ovu poruku je menjao Boris B. dana 09.12.2010. u 15:38 GMT+1]
if it walks like a duck and quacks like a duck, it could be a dragon doing a duck
impersonation.
 
Odgovor na temu

mmix
Miljan Mitrović
Profesorkin muz
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6042



+4631 Profil

icon Re: Covariance sa IS operatorom - Kako resiti ovo?09.12.2010. u 14:52 - pre 162 meseci

>mislio sam da je to samo templating engine koji radi search&replace pred kompajliranjem.

C# Generics nije isto sto i C++ templates, C# kompajler pravi specijalizaciju ali zadrzava informacije u Type objektu.
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan, sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv… - Z.Đinđić
 
Odgovor na temu

[es] :: .NET :: Covariance sa IS operatorom - Kako resiti ovo?

[ Pregleda: 1383 | Odgovora: 8 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.