1

How i can use ref of a generic class as parameter and change data. Here is my sample code

bool IRequestHandler.ParseRequest<T>(string request, ref T obj)
{
    var req = RequestHandlerGateway.DeserializeFromXml<OrderMessageSalesOrder>(request, "SalesOrder");

    return false;
}

I want to update data inside obj.

Erik Dietrich
  • 6,080
  • 6
  • 26
  • 37
RPK
  • 33
  • 1
  • 5

4 Answers4

1

There's not much you can do with the "T obj" unless you inform the compiler what additional interfaces it supports.

E.g.

IRequestHandler.ParseRequest<T>(string request, T obj)
where T : IOrderInfo
{
    var req = RequestHandlerGateway.DeserializeFromXml<OrderMessageSalesOrder>(request, "SalesOrder");
    obj.OrderId = req.Id;
    return true;
}

Assuming IOrderInfo defines the OrderId property, and OrderMessageSalesOrder provides the Id property (or field).

The ref is only needed if you intend to create a new T instance:

IRequestHandler.ParseRequest<T>(string request, ref T obj)
where T : IOrderInfo, new()
{
    var req = RequestHandlerGateway.DeserializeFromXml<OrderMessageSalesOrder>(request, "SalesOrder");
    obj = new T();
    obj.OrderId = req.Id;
    return true;
}

If you intend to cast the deserialized object req to obj, the above answers should be sufficient, but then I think you're on shaky ground.

Robert Schmidt
  • 699
  • 4
  • 14
0

You can cast the result of your deserialization to an object, then cast it to T, but make sure that the object that you are getting from your DeserializeFromXML method is of type T

bool IRequestHandler.ParseRequest<T>(string request, ref T obj)
{
    var req = RequestHandlerGateway.DeserializeFromXml<OrderMessageSalesOrder>(request, "SalesOrder");

    obj = (T)(object)(req);    // Careful here

    return false;
}

Since this is a generic method, any type can be passed in for obj, but your method looks like it is creating a very specific type (OrderMessageSalesOrder). You may want to reconsider why you need this to be generic in the first place

Tung
  • 5,334
  • 1
  • 34
  • 41
0

Ref is often used for typed values. If your obj parameter is of reference types(since you name it "obj"), there's no need to add ref key word. To change the obj's value, you need to give it a type. One way is to use type conversion, like:

MyTyped myObj = (MyTyped)obj;

And setting values for myObj will change values for obj also(because it's a reference).

Also if you can find a base Class/Interface for obj, simply change your code as:

bool IRequestHandler.ParseRequest<BaseClass>(string request, BaseClass obj)
Chris Li
  • 3,715
  • 3
  • 29
  • 31
0

You don't need to use the ref keyword if you are dealing with classes instead of structs since they are always passed by reference anyway. You might want to use the out keyword instead, a couple of changes would improve it.

bool IRequestHandler.ParseRequest<T>(string request, out T obj)
{
    try
    {
        var req = RequestHandlerGateway.DeserializeFromXml<T>(request, "SalesOrder");
        obj = req;
        return true;
    }
    catch
    {
        obj = default(T);
        return false;
    }
}

That way you can then call it as follows:

OrderMessageSalesOrder salesOrder;

if(handler.ParseRequest(request, out salesOrder))
{
    // parsed successfully, salesOrder will be an instance populated with the data in the request.
}
else
{
    // unable to parse, salesOrder will be null.
}
Trevor Pilley
  • 16,156
  • 5
  • 44
  • 60