在.NET C#中将动态对象转换为具体对象

8

如您从标题中所见,我需要将此对象转换为:

    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://dev59.com/d2Qn5IYBdhLWcg3wGD5s#17322347

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


new Student(obj.Id, obj.Name) 是什么意思?或者我完全错过了什么? - pijemcolu
@Androidmuster:- 你如何区分从前端传递到API的对象是“学生”还是“学者”?我认为你想传递一个对象,并根据需求将其转换为相关类。 - DhavalR
当你从前端传递对象时,属性的数量和类型必须相同,同时也要考虑它的含义。这是可能的还是不可能的,你需要考虑清楚。 - DhavalR
2
这里有两个问题需要解决,首先像@Androidmuster所说的那样,您必须能够确定哪种类型是动态对象中数据的适当容器(仅基于问题提供的信息,我没有看到可靠的方法)。然后,您可以覆盖类上的显式转换运算符,以允许从对象到您的类的具体实例的显式转换(在Google上搜索,有许多示例)。 - Kevin
我很感激你们的帮助。每一个评论对我来说都是有用的。@Kevin,也许你可以给我提供一个好的/正确的“互联网示例”。 - Androidmuster
显示剩余7条评论
1个回答

11

您可以使用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模式,然后检查新数据是否符合此模式来实现的。


谢谢你的帮助。这个解决方案正是我所需要的。 - Androidmuster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接