2012-03-07 2 views
1

Как я могу использовать ref общего класса в качестве параметра и изменить данные. Вот мой пример кодассылочные объекты в generics C#

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

    return false; 
} 

Я хочу обновить данные внутри объекта.

+0

Ваш код в порядке. В чем проблема? – Candide

+0

Что такое «Т» в вашем примере? Это OrderMessageSalesOrder? –

+0

T - общий параметр –

ответ

0

Вы можете привести результат вашей десериализации на объект, а затем привести его к T, но убедитесь, что объект, который вы получаете от вашего метода DeserializeFromXML имеет типа 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; 
} 

Поскольку это общий метод, любой тип может быть передан для obj, но ваш метод выглядит так, будто он создает очень специфический тип (OrderMessageSalesOrder). Возможно, вы захотите пересмотреть, почему вам нужно, чтобы это было общее в первую очередь.

0

Ссылка часто используется для типизированных значений. Если ваш параметр obj имеет ссылочные типы (поскольку вы называете его «obj»), нет необходимости добавлять ключевое слово ref. Чтобы изменить значение obj, вам нужно указать тип. Один из способов заключается в использовании преобразования типов, например:

MyTyped myObj = (MyTyped)obj; 

И установка значения myObj будет изменять значения для OBJ также (потому что это ссылка).

Кроме того, если вы можете найти базовый класс/интерфейс для OBJ, просто изменить код, как:

bool IRequestHandler.ParseRequest<BaseClass>(string request, BaseClass obj) 
0

Вам не нужно использовать ref ключевое слово, если вы имеете дело с классами, а не так структур они все равно передаются по ссылке. Вместо этого вы можете использовать ключевое слово out, а несколько изменений улучшат его.

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; 
    } 
} 

Таким образом, то вы можете назвать это следующим образом:

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. 
} 
1

Там не много вы можете сделать с «T OBJ», если не сообщить компилятору, какие дополнительные интерфейсы, которые он поддерживает.

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; 
} 

Предполагая, что IOrderInfo определяет свойство OrderId и OrderMessageSalesOrder обеспечивает свойство Id (или поле).

терпение только необходимо, если вы собираетесь создать новый T экземпляр:

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; 
} 

Если вы собираетесь бросить десериализованный REQ объектных OBJ, вышеуказанные ответы должны быть достаточно, но я думаю, что вы на дрожащей земле.

Смежные вопросы