gpt4 book ai didi

c# - 从另一个实例创建新对象

转载 作者:行者123 更新时间:2023-12-03 20:31:28 26 4
gpt4 key购买 nike

我发现了类似的问题,但我仍然遇到麻烦:

  1. Dynamically create an object of <Type>
  2. Get a new object instance from a Type

-- 希望对问题有更好的描述?----

当我调用网络服务时,带回的响应是一个xml文档。该文档定义了要返回的类,然后通过将 xml 反序列化为 8 种不同类型中的一种来设置所有值。

现在,当我执行 receipt.Item 时,我得到了返回的类型;但是由于使用 Web 服务调用设置接口(interface)的方式,我无法访问任何项目成员变量,除非我键入 cast receipt.Item。这是通过开关盒完成的。但是我想要在 switch case 之外创建对象并在 switch case 内部初始化它,这样我就可以稍后在代码中访问它。这就是为什么我不在 switch case 中创建该类型的新对象并在那里工作(或调用函数)的原因。


我调用的 Web 服务有一个总体返回类型 Response,该 Web 服务可以有 8 种不同的结果类型。我需要创建一个可以返回的 8 种返回类型中的第一种的实例。

所以这里是为了更直观的结构

Response
accountUpdaterRespType
endOfDayRespType
flexCacheRespType

响应对象的代码:

public partial class Response {

private object itemField;

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("AccountUpdaterResp", typeof(accountUpdaterRespType))]
[System.Xml.Serialization.XmlElementAttribute("EndOfDayResp", typeof(endOfDayRespType))]
[System.Xml.Serialization.XmlElementAttribute("FlexCacheResp", typeof(flexCacheRespType))]
public object Item {
get {
return this.itemField;
}
set {
this.itemField = value;
}
}
}

当我获得 Response 的返回对象时,我可以通过执行 responseObject.Item 并对其执行 GetType() 来获取类型。这就是我可以用来尝试对新对象进行类型转换的方法。

我必须这样做,因为当我执行 responseObject.Item 时,我无法访问不同对象类型中的不同变量。所以我想像这样在 switch case 中输入一个新对象:

object newReceipt = Receipt.GetType(); //this is where I would get the type I assume?? I don't know

string type = Receipt.Item.GetType().ToString();

switch (type)
{
case "accountUpdaterRespType":
newReceipt = (accountUpdaterRespType)Receipt.Item;

break;
case "endOfDayRespType":
newReceipt = (endOfDayRespType)Receipt.Item;
break;
case "flexCacheRespType":
newReceipt = (flexCacheRespType)Receipt.Item;
break;
}

最佳答案

在回答之前,我会尝试重述您的问题。

您正在尝试创建对现有实例的类型化引用。您已经有一个对象的实例,保存在 object 类型的变量中,但想要将其向上转换以便能够访问成员。

通过在代码中获取变量类型,您仍然无法在开发时访问对象成员。

使用字符串来检查对象类型不是一个好主意。您的问题的有效解决方案如下

// as is a type of cast. if Receipt is of type cast,
// it will return an object and put it into accountUpdater
// variable. If Receipt is not of that type, it will place null
// into accountUpdater variable
var accountUpdater = Receipt.Item as accountUpdater;
if (accountUpdater != null)
{
// Do something with account updater here. E.g.
Console.WriteLine(accountUpdater.SomeAccountUpdaterProperty);
}
var endOfDayResp = Receipt.Item as endOfDayRespType;
if (endOfDayResp != null)
{
// Do something with endOfDayResp here
}
var flexCache = Receipt.Item as flexCacheRespType;
if (flexCache != null)
{
// Do something with flex cache here
}

你明白了。请注意,这不是编写代码的好方法。上面的示例只是为了让您启动并运行。您应该熟悉面向对象的编程概念,尤其是对于这种情况,多态性。

另一种(基本相同的)处理方式是:

var accountUpdater = Receipt.Item as accountUpdater;
if (Receipt.Item is accountUpdater)
HandleAccountUpdater((accountUpdater)Receipt.Item);
else if (Receipt.Item is endOfDayRespType)
HandleEndOfDay((endOfDayRespType)Receipt.Item);
else if (Receipt.Item is flexCacheRespType)
HandleFlexCache((flexCacheRespType)Receipt.Item);
else
throw new InvalidArgumentException("Unexpected parameter type");

你是对的,多态性是在对象具有相似特征并且需要以相似方式处理的情况下的解决方案。上面的两个解决方案是您无需进一步了解 C# 语言即可完成的最佳方式。第二种解决方案提供更好的职责分离。


您可以使用 reflection 获得更通用的解决方案.使用 System.Reflection 中的方法,您可以对处理程序方法进行更通用的解析。以下面的例子:

如您所述,您有 Response 对象。您还有一个可以处理不同类型对象的类。例如:

public class ResponseHandler
{
public void Handle(accountUpdater parameter) { /* */ }
public void Handle(endOfDayRespType parameter) { /* */ }
public void Handle(flexCacheRespType parameter) { /* */ }
public void Handle(TypeD parameter) { /* */ }
public void Handle(TypeE parameter) { /* */ }
...
}

收到响应后,您将能够确定动态调用哪个处理程序,而无需手动添加每个类型,如下所示:

var handler = new ResponseHandler();
var handlerClassType = typeof(ResponseHandler); // This is how you get Type object from a type. Unlike, `GetType` on objects
var paramType = Response.Item.GetType();
// Get me method which is named Handle and takes parameters in parameter array
// handlerMethod will be of type MethodInfo. This is basically a descriptor of a
// method. Not a pointer to a method or some such...
var handlerMethod = handlerClassType.GetMethod("Handle", new Type[] { paramType });
// Throw exception if we don't know how to handle it
if (handlerMethod == null)
throw new Exception("Handler not found for received response type");
// Invoke the handler. We need to provide the method descriptor with object which
// should execute the method, and parameters that the method takes
handlerMethod.Invoke(handler, new object[] { Response.Item });

这是在 SO 编辑器中编写的,因此它可能不会立即运行:)

关于c# - 从另一个实例创建新对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18707573/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com