Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use a variable as type

Tags:

c#

wcf

transfer

I want to transfer BusinessObjects from one PC to another. If I think about a number of around 40 different object types to transfer the use of many contracts for the different objects would seem to be quite some overload for always the same task: "Send Object A to Computer B and save object to DB" (objects all have a persistent method).

As the Objects can have many different types, I only want to to use a generic method to:

  1. serialize a BO object
  2. transfer it to another PC
  3. deserialize it with correct type
  4. make a consistency check
  5. save to db
  6. is my problem.

At the moment I'm thinking about sending the type as eytra information. Then I want to do something like:

BinaryFormatter aFormatter = new BinaryFormatter();
aFormatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
Object.ParseTypeFromString(aObjektType) aObject = aFormatter.Deserialize(stream) as Object.ParseTypeFromString(aObjektType);

And afterwards just use generic methods from a base object to save object to database, to keep the transfer classes as simple as possible.

Is there a possibility to do something like this? Or am I going in a completly wrong direction and it would be easier to achieve this task with another approach?

like image 250
Offler Avatar asked Oct 09 '12 06:10

Offler


1 Answers

If you don't know the type in advance, you cannot currently be doing anything in the C# that depends on the type. BinaryFormatter will already be deserializing it with the correct object type, but you code can usually just refer to the object as.... object:

object aObject = aFormatter.Deserialize(stream);

At this point, there are various options available to you:

  • use a common interface / base-class
  • use dynamic (interesting uses of dynamic include calling the most appropriate overload of a method, and switching into a generic method)
  • test the type explicitly with is, as or GetType(), for special-casing

As an example of the middle option:

object aObject = aFormatter.Deserialize(stream);
GenericMagic((dynamic)aObject);
OverloadMagic((dynamic)aObject);

...

void GenericMagic<T>(T obj) // possibly some constraints here too
{
    T x = ... // now we *have* the type, but as `T`;
              // of course, you still can't do many exciting
              // things unless you add constraints
}

// the correct one of these will be chosen at runtime...
void OverloadMagic(Customer cust) {...}
void OverloadMagic(User user) {...}
void OverloadMagic(Order order) {...}

Frankly, if I've had to deserialize (etc) something unknown I usually prefer to stay non-generic, just using object, GetType(), and maybe some reflection - it is still generic, even if it doesn't use generics.

like image 75
Marc Gravell Avatar answered Oct 26 '22 18:10

Marc Gravell