[C#] Serializable object casten

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • dtech
  • Registratie: Juni 2005
  • Laatst online: 13-06 23:19
Hallo,

ik heb een paar objecten die ik serialize en over het netwerk verstuur. Sommigen implementen ISerializable, maar sommigen laten het gewoon door .NET zelf doen.
Nu wil ik een methode maken die de inkomende objecten accepteert, maar ik wil voorkomen dat niet-serializable objecten mee worden gegegeven aan de methode.

Mijn vraag is dus of ik op een makkelijke manier zo'n check can doen, het volgende werkt niet:
code:
1
2
3
4
Object o = Receive();
if(o is ISerializable){
    // All quiet on the western front
}


Maar dat kan dus niet omdat niet elk object ISerializable implementeerd.

Ik kan natuurlijk ook ingewikkeld gaan doen met Reflection en het serializable attribuut controleren, maar daar heb ik niet veel zin in en ik vind het wat overkill en onnodig vertragend (Reflection is niet echt snel natuurlijk).

Weet iemand of dit wel kan?

Acties:
  • 0 Henk 'm!

  • dtech
  • Registratie: Juni 2005
  • Laatst online: 13-06 23:19
Nog iets wat ik raar vind, de deserialisation functions geven wel allemaal ISerializable's terug, maar je kunt ze converten naar objecten die daar niet van erven! is dat niet een enorme inconsistency? Het klopt ook niet volgens oop, daar hoor je altijd het volgende te kunnen doen:
code:
1
2
3
Hoofdklasse a = new Subklasse();
Subklasse b = (Subklasse) a;
Hoofdklasse c = b;


Terwijl dit dus hier niet kan:
code:
1
2
3
ISerializable a = Receive();
CustomObject b = (CustomObject)a;
ISerializable c = (ISerializable)b;


Volledig contra-intuïtief!

edit:

Disregard that, ik dacht dat de functie die mijn projectgenoten hadden geschreven ByteArrayToObject een standaard .NET functie was, daar zat dus de fout, die hoort gewoon een object mee te geven

[ Voor 15% gewijzigd door dtech op 28-05-2010 11:10 ]


Acties:
  • 0 Henk 'm!

  • ThomasG
  • Registratie: Juni 2006
  • Laatst online: 13-09 17:43
Waarom maak je geen gebruik van de IsSerializable eigenschap op de Type klasse?

code:
1
2
3
4
Klasse a = new Klasse();
if (a.GetType().IsSerializable) { // of: typeof(Klasse).IsSerializable
    // Doe iets leuks
}

Acties:
  • 0 Henk 'm!

  • fiftyhillswest
  • Registratie: Oktober 2009
  • Laatst online: 11-09 18:26
Ik heb een ranzige oplossing gevonden die werkt voor beide situaties met behulp van dit blog: http://www.hanselman.com/...ImplementAnInterface.aspx

Komt ie:
C#:
1
2
3
if (typeof(Receive).IsSerializable || typeof(Receive).GetInterface("ISerializable").FullName == "System.Runtime.Serialization.ISerializable") {
     //doe je ding
}


Het maakt nu niet uit hoe je de class declared.
C#:
1
2
3
4
5
6
//het kan dus zo...
class Receive : ISerializable {}

//of zo...
[Serializable]
class Receive {}


Toch wel een beetje slecht dat .Net hier niet standaard iets voor heeft. 8)7

Acties:
  • 0 Henk 'm!

  • DutchCommando
  • Registratie: November 2000
  • Laatst online: 22:25
fiftyhillswest schreef op vrijdag 28 mei 2010 @ 18:07:
Toch wel een beetje slecht dat .Net hier niet standaard iets voor heeft. 8)7
Het SerializableAttribute moet je boven classes zetten die je wilt kunnen serializen. Middels een eigen implementatie van de ISerializable interface kan je zelf meer invloed uitoefenen op het serializatieproces. Hier is werkelijk waar niks vreemds aan. Het controleren van Type.IsSerializable zou afdoende moeten zijn, omdat alle ISerializable implementing classes ook het SerializableAttribute zouden moeten bevatten.

Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
DutchCommando schreef op vrijdag 28 mei 2010 @ 20:14:
[...]


Het SerializableAttribute moet je boven classes zetten die je wilt kunnen serializen. Middels een eigen implementatie van de ISerializable interface kan je zelf meer invloed uitoefenen op het serializatieproces. Hier is werkelijk waar niks vreemds aan. Het controleren van Type.IsSerializable zou afdoende moeten zijn, omdat alle ISerializable implementing classes ook het SerializableAttribute zouden moeten bevatten.
Klopt precies. Verder maakt het voor het deserializatie proces niet uit of een class ISerializable wel of niet implementeert.Vanuit het oogpunt van de consument van die class loopt alles gewoon nog steeds via de Deserialize() method van een formatter class die de IFormatter interface implementeert. Bijvoorbeeld de standaard BinaryFormatter, waar alles al in zit om complete object grafen te (de)serializeren naar/van een stream die je zo over het netwerk heen kunt sturen. Verder beschikt het serializatie framework binnen .NET ook al over een aantal attribute classes om veel voorkomende scenario's te regelen, zoals properties wel/niet te (de)serializeren. Voor dat soort dingen hoef je dan niet eens ISerializable te implementeren, maar is alleen het SerializableAttribute al afdoende.

Lijkt er op dat dtech en zijn projectgenoten dapper bezig zijn geweest het vierkante wiel opnieuw uit te vinden.

Acties:
  • 0 Henk 'm!

  • fiftyhillswest
  • Registratie: Oktober 2009
  • Laatst online: 11-09 18:26
DutchCommando schreef op vrijdag 28 mei 2010 @ 20:14:
[...]


Het controleren van Type.IsSerializable zou afdoende moeten zijn, omdat alle ISerializable implementing classes ook het SerializableAttribute zouden moeten bevatten.
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    class Program {
        static void Main(string[] args) {
            Console.WriteLine("Receive.isSerializable: {0}", typeof(Receive).IsSerializable); //Geeft False 
            Console.WriteLine("Send.isSerializable: {0}", typeof(Send).IsSerializable); // Geeft True 
            Console.ReadLine();
        }
    }
    class Receive : ISerializable {
        public void GetObjectData(SerializationInfo info, StreamingContext context) {
            throw new NotImplementedException();
        }
    }

    [Serializable]
    class Send {
    }


Niet dus....

Acties:
  • 0 Henk 'm!

  • DutchCommando
  • Registratie: November 2000
  • Laatst online: 22:25
fiftyhillswest schreef op zondag 30 mei 2010 @ 15:06:
[...]


C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    class Program {
        static void Main(string[] args) {
            Console.WriteLine("Receive.isSerializable: {0}", typeof(Receive).IsSerializable); //Geeft False 
            Console.WriteLine("Send.isSerializable: {0}", typeof(Send).IsSerializable); // Geeft True 
            Console.ReadLine();
        }
    }
    class Receive : ISerializable {
        public void GetObjectData(SerializationInfo info, StreamingContext context) {
            throw new NotImplementedException();
        }
    }

    [Serializable]
    class Send {
    }


Niet dus....
Ja, wat hier gebeurt klopt. Maar je geeft dan ook niet aan dat Receive Serializable is.

Acties:
  • 0 Henk 'm!

  • fiftyhillswest
  • Registratie: Oktober 2009
  • Laatst online: 11-09 18:26
D'OH! 8)7

Hier blijkt weer eens uit dat ik al veel te lang niets meer met ISerializable heb gedaan. :P
Ging er blijkbaar vanuit dat als je ISerializable implementeerde dat je dan al aangaf dat hij serializable was. Maar je hebt gelijk. Dan geven ze wel allebei True en dus zou de IsSerializable genoeg moeten zijn.
Pagina: 1