Overiding generic functions

  • Thread starter Thread starter colin
  • Start date Start date
C

colin

Hi,
If i have a set of overloaded serialization routines such as
void Serialize(ref Int32 x);
void Serialize<T>(ref T x);

this works great,... when I call the function with an int32 it calls the
first one,
any other type it calls the second one.

however If i have a serializer for a generic array
void SerializeArray<T>(ref T[] array)
{
for(int x...)
Serialize(ref array[x]);
}
it always calls the generic function even if its an array of ints,
how do i get round this so it calls the first one if its an array of ints
wothout doing a test to see if its one of the many diferent types ?

the generic function is going to be slow, probably using reflection,
so I want to call it only for complex classes or ones wich dont apear very
often,
but for all the system types and a few often used structs/classes
I want to call specific functions.

so whats the best way to implement the array serializer,
without writing a seperate one for all the system types?

I also need to have several diferent types of array serializers as some use
one of two forms of storage.
some data types need to be serialized diferently ie some int64 are packed so
that the most significant
bytes arnt stored if they are zero (or 255 for negative numbers). with
arrays of these types too.


Colin =^.^=
 
Peter Duniho said:
If i have a set of overloaded serialization routines such as
void Serialize(ref Int32 x);
void Serialize<T>(ref T x);

this works great,... when I call the function with an int32 it calls the
first one,
any other type it calls the second one.

however If i have a serializer for a generic array
void SerializeArray<T>(ref T[] array)
{
for(int x...)
Serialize(ref array[x]);
}
it always calls the generic function even if its an array of ints,
how do i get round this so it calls the first one if its an array of ints
wothout doing a test to see if its one of the many diferent types ?

I believe that the reason the non-generic method isn't used is that the
compiler needs to decide when your generic SerializeArray() method is
compiled which method to call. At that point, it has no way to know the
type being passed in (it's a generic method, after all). The only way
that it could know that is to defer compilation of the generic method
until the point at which it's actually used. But then you'd have to have
a different compiled generic method for each use, which negates one of the
main advantages of generics in C#.

If you're going to have situations where you want to use some specific
non-generic method, I think you'll need some specific non-generic array
method to call it so that the compiler knows at the time it generates the
call what the type is.

thanks yeah I guesed it was something like that, it makes sense,
but it need a lot of different functions wich is why id rather use generic,
id rather the compiler generate loads of different functions at compile time
than have to do it by hand.

Ive tried passing it a delegate wich would probably be quicker than doing a
test in the routine for each element.

if i have my serializer :-
public abstract class SerializeStream
{
public delegate void serlizer<T>(ref T data);
public abstract void SerializeArray<T>(ref T[] array, serlizer<T>
serialize);
....
}
and call
file.SerializeArray(ref NameTable,file.Serialize);

luckily it picks up the non generic function and passes it to the array
serializer,
presumably its becuse it does it before it goes all generic.

I still need to cope with the case where the array element type class has
its own serialization routine,
I expect I can use a delegate here too but the syntax is doing my head in
trying to get it right,
although its expecting a function to be a meber of the serialize class, not
a diferent class :s
I cant use a static method becuase it needs to be overriden.

theres probably 100mb of data to be serialised this way, using reflection
everywhere is quite slow,
although neccessary for some user added classes.

Colin =^.^=
 
colin said:
Peter Duniho said:
If i have a set of overloaded serialization routines such as
void Serialize(ref Int32 x);
void Serialize<T>(ref T x);

this works great,... when I call the function with an int32 it
calls the first one,
any other type it calls the second one.

however If i have a serializer for a generic array
void SerializeArray<T>(ref T[] array)
{
for(int x...)
Serialize(ref array[x]);
}
it always calls the generic function even if its an array of ints,
how do i get round this so it calls the first one if its an array
of ints wothout doing a test to see if its one of the many diferent
types ?

I believe that the reason the non-generic method isn't used is that
the compiler needs to decide when your generic SerializeArray()
method is compiled which method to call. At that point, it has no
way to know the type being passed in (it's a generic method, after
all). The only way that it could know that is to defer compilation
of the generic method until the point at which it's actually used. But
then you'd have to have a different compiled generic method for
each use, which negates one of the main advantages of generics in C#.

If you're going to have situations where you want to use some
specific non-generic method, I think you'll need some specific
non-generic array method to call it so that the compiler knows at
the time it generates the call what the type is.

thanks yeah I guesed it was something like that, it makes sense,
but it need a lot of different functions wich is why id rather use
generic, id rather the compiler generate loads of different functions
at compile time than have to do it by hand.

Ive tried passing it a delegate wich would probably be quicker than
doing a test in the routine for each element.

if i have my serializer :-
public abstract class SerializeStream
{
public delegate void serlizer<T>(ref T data);
public abstract void SerializeArray<T>(ref T[] array, serlizer<T>
serialize);
....
}
and call
file.SerializeArray(ref NameTable,file.Serialize);

luckily it picks up the non generic function and passes it to the
array serializer,
presumably its becuse it does it before it goes all generic.

I still need to cope with the case where the array element type class
has its own serialization routine,
I expect I can use a delegate here too but the syntax is doing my
head in trying to get it right,
although its expecting a function to be a meber of the serialize
class, not a diferent class :s
I cant use a static method becuase it needs to be overriden.

theres probably 100mb of data to be serialised this way, using
reflection everywhere is quite slow,
although neccessary for some user added classes.

Use reflection to grab the serializer method and create a delegate, use a
dictionary to cache the result so you only need to do that once per type.
 
Use reflection to grab the serializer method and create a delegate, use a
dictionary to cache the result so you only need to do that once per type.

yeah thats quite a good aproach, actually ive used it to handle the
reflection on some of the more complicated stuff,
as it was quite slow but with the simpler functions I was hoping to have
next to no look up,
fortunatly passing a delegate from outside the generic function it picks up
the non generif function ok.

It taxes me a bit trying to work out the way to use delegates where the
function is a ref parameter of different types,
as I cant make the parameter an object and stil be able to pass it as a
reference.

ive tended to avoid trying to do it this way for the stuff that will get
used heavily.

Colin =^.^=
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top