简体   繁体   English

泛型C#中的引用对象

[英]reference objects in generics c#

How i can use ref of a generic class as parameter and change data. 我如何使用泛型类的ref作为参数并更改数据。 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. 我想更新obj中的数据。

There's not much you can do with the "T obj" unless you inform the compiler what additional interfaces it supports. 除非您告知编译器它支持哪些其他接口,否则“ T obj”几乎不能做任何事情。

Eg 例如

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). 假设IOrderInfo定义了OrderId属性,而OrderMessageSalesOrder提供了Id属性(或字段)。

The ref is only needed if you intend to create a new T instance: 仅当您打算创建新的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;
}

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. 如果打算将反序列化的对象req强制转换为obj,则上面的答案应该足够了,但是我认为您的处境不稳。

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 您可以将反序列化的结果强制转换为一个对象,然后将其强制转换为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;
}

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). 由于这是一个通用方法,因此可以为obj传递任何类型,但是您的方法似乎正在创建一个非常特定的类型(OrderMessageSalesOrder)。 You may want to reconsider why you need this to be generic in the first place 您可能想重新考虑为什么首先需要将此泛型

Ref is often used for typed values. Ref通常用于键入的值。 If your obj parameter is of reference types(since you name it "obj"), there's no need to add ref key word. 如果您的obj参数是引用类型(因为您将其命名为“ obj”),则无需添加ref关键字。 To change the obj's value, you need to give it a type. 要更改obj的值,需要给它一个类型。 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). 并且为myObj设置值也会更改obj的值(因为这是参考)。

Also if you can find a base Class/Interface for obj, simply change your code as: 另外,如果您可以找到obj的基本类/接口,则只需将代码更改为:

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

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. 如果要处理类而不是结构,则无需使用ref关键字,因为无论如何它们总是通过引用传递的。 You might want to use the out keyword instead, a couple of changes would improve it. 您可能要改用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;
    }
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM