【问题标题】:Convert a dynamic object to a concrete object in .NET C#在 .NET C# 中将动态对象转换为具体对象
【发布时间】:2018-04-25 22:01:54
【问题描述】:

正如你从标题中看到的,我需要转换这个对象:

    object obj = new{
       Id = 1,
       Name = "Patrick"
    };

到特定的类实例。

为了更清楚,这里给你们举个例子:

    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }

    }

    public class Scholar
    {
        public int UniqueId { get; set; }
        public string FullName { get; set; }

    }

我有两个班级学生学者。我想不出一种方法来正确编写转换为特定类型的算法。

在我看来,伪代码应该是这样的:

if (obj.CanBeConverted<Student>()) {
   //should return this if statement

   obj = ConvertToType<Student>(o);

   // after this method obj type should change to Student
} else if (obj.CanBeConverted<Scholar>()) {

   //at current example wont reach this place
  obj = ConvertToType<Scholar>(o);

  // after this method obj type should change to Scholar
}

这可能以某种方式编程吗?


我上网找到了这个例子:https://stackoverflow.com/a/17322347/8607147

但是,此解决方案总是尝试将对象或动态类型转换/反序列化为具体对象。

【问题讨论】:

  • 我的第一个问题是:这个匿名对象首先来自哪里,你不能让它返回一个具体的类型吗?
  • new Student(obj.Id, obj.Name) 呢?或者我在这里完全错过了什么?
  • @DavidG 这个对象来自前端到 API。我想将动态类型对象传递给 API 方法转换为具体类型,然后对其进行一些处理。
  • 好的,这仍然不能回答我的问题。为什么与 API 对话的代码会给你一个匿名类型?我做了很多 API 工作,从不担心这个。
  • 这里有两个问题需要解决,首先就像@Androidmuster 所说,您必须能够确定您的哪些类型是动态对象中数据的合适容器(仅基于提供的内容)在这个问题中,我没有看到可靠的方法)。然后,您可以覆盖类上的显式转换运算符,以允许从对象显式转换为您的类的具体实例(谷歌它,互联网上有很多示例)。

标签: c# object dynamic reflection


【解决方案1】:

你可以使用Json.Net SchemaJson.Net来做到这一点,看看我是怎么做到的:

  class Program
  {
    static void Main(string[] args)
    {
      var o = new
      {
        Id = 1,
        Name = "Patrick",
        Courses = new[] { new { Id = 1, Name = "C#" } }
      };

      Student student = null;
      Scholar scholar = null;

      if (o.CanBeConverted<Student>())
        student = o.ConvertToType<Student>();
      else if (o.CanBeConverted<Scholar>())
        scholar = o.ConvertToType<Scholar>();

      System.Console.WriteLine(student?.ToString());
      System.Console.WriteLine(scholar?.ToString());

      System.Console.ReadKey();
    }
  }

  public static class ObjectExtensions
  {
    public static bool CanBeConverted<T>(this object value) where T : class
    {
      var jsonData = JsonConvert.SerializeObject(value);
      var generator = new JSchemaGenerator();
      var parsedSchema = generator.Generate(typeof(T));
      var jObject = JObject.Parse(jsonData);

      return jObject.IsValid(parsedSchema);
    }

    public static T ConvertToType<T>(this object value) where T : class
    {
      var jsonData = JsonConvert.SerializeObject(value);
      return JsonConvert.DeserializeObject<T>(jsonData);
    }
  }

  public class Student
  {
    public int Id { get; set; }
    public string Name { get; set; }
    public Courses[] Courses { get; set; }

    public override string ToString()
    {
      return $"{Id} - {Name} - Courses: {(Courses != null ? String.Join(",", Courses.Select(a => a.ToString())) : String.Empty)}";
    }
  }

  public class Courses
  {
    public int Id { get; set; }
    public string Name { get; set; }

    public override string ToString()
    {
      return $"{Id} - {Name}";
    }
  }

  public class Scholar
  {
    public int UniqueId { get; set; }
    public string FullName { get; set; }

    public override string ToString()
    {
      return $"{UniqueId} - {FullName}";
    }
  }

解决方案基本上是通过从所需对象生成 JSON Schema 并检查新数据是否适合此 shema。

【讨论】:

  • 感谢您的帮助。这个解决方案正是我所需要的。
猜你喜欢
  • 2012-10-21
  • 1970-01-01
  • 2010-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
  • 2023-04-01
  • 1970-01-01
相关资源
最近更新 更多