在 C# 中不使用反射将对象转换为用户定义类型 class 对象

Convert an Object to a user defined type class object without Reflection in C#

我有以下代码,我在数组中添加一些 class 对象。

  Object[] ArrayOfObjects = new Object[] {typeof(Person), typeof(Company)};

现在,如果我想遍历我的 class 项目,我如何才能将每个项目转换回其原始类型(例如个人和公司)?这可能可以使用反射,但我想知道 C# 是否有一些内置功能来实现这一点。

  foreach (var item in ArrayOfObjects)
  {
     // TODO Convert item back to Original Type (Person or Company)
     // I am doing something like this but not working
     var person  =  Convert.ChangeType(item, typeof(Person));

     //I can not do this too as hardcoding the type inside the loop makes no sense
     var person = item as Person; //I need to convert item as Person or Company so that i can automate the tasks here.
  }

非常感谢。

using System;

namespace PatternMatching
{
    class Person
    {
        public void PersonMethod() => throw new Exception();
    }

    class Company
    {
        public void CompanyMethod() => throw new Exception();
    }

    class Program
    {
        static void Main(string[] args)
        {
            Object[] ArrayOfObjects = { new Person(), new Company() };

            foreach (var item in ArrayOfObjects)
            {
                if (item is Person person)
                {
                    person.PersonMethod();
                }

                if (item is Company company)
                {
                    company.CompanyMethod();
                }
            }
        }
    }
}

使用模式匹配 (C# 8.0+) https://docs.microsoft.com/en-us/archive/msdn-magazine/2019/may/csharp-8-0-pattern-matching-in-csharp-8-0 您甚至可以为此使用开关模式。

对您的用例做出一些假设,您可能会受益于使用接口来完全消除转换对象的需要

假设你需要执行共享方法 Foo,它同时属于 Company 和 Person

public interface ObjectWithFoo{
     void Foo();
}
public class Person : ObjectWithFoo{
    ...
}
public class Company: ObjectWithFoo{
    ...
}

然后在您的主代码中创建一个 ObjectWithFoo 列表

ObjectWithFoo[] myArray = new ObjectWithFoo[]{new Person(), new Company()}

然后在你的循环中

foreach(var objectWithFoo in myArray)
    objectWithFoo.Foo();

这样你根本不需要转换,你可以只使用接口来处理所有事情。额外的好处是,您的数组对您自己和其他人的用途变得更加清晰 - 它仅用于属于您的界面的 methods/attributes。如果您使用对象数组,人们可以轻松添加不受支持的类型或开始在其他地方使用该列表,并使您的代码有点混乱。