C# 创建实例后,如何将其强制转换为创建的类型

C# 创建实例后,如何将其强制转换为创建的类型,c#,C#,假设我有一个返回类型的方法: private Type GetPersonOrOrganisation(someParameter) { either return Person type or Organisation type } 然后我把这个方法叫做: Type type = GetPersonOrOrganisation(someParameter); 然后,我尝试创建返回类型的新实例: var newContact = Activator.CreateInstance(type

假设我有一个返回类型的方法:

private Type GetPersonOrOrganisation(someParameter)
{
  either return Person type or Organisation type
}
然后我把这个方法叫做:

Type type = GetPersonOrOrganisation(someParameter);
然后,我尝试创建返回类型的新实例:

var newContact = Activator.CreateInstance(type);
我剩下的是newContact的类型是object。我想要的是新联系人的类型可以是Person,也可以是Organization,具体取决于从GetPersonorOrganization返回的内容


有人知道如何将newContact转换为正确的类型吗?

这肯定有一些代码味道。但也许有一些方法可以解决这个问题

你可能想考虑一个人和组织实现的接口,如果你要用同样的方式与它们交互。或者是一个基类,这取决于您的具体场景

除此之外,我们可能还需要您在之后尝试做的事情,以便能够提供建议。如果没有接口(或其他一些基类),就不能有一个对象可以是这两种类型中的任何一种。目前他们唯一的共同点是对象


您可以执行一些不同的操作,如
if(newContact是Person){}else if(newContact是organization){}
或类似操作,具体取决于您的场景,但这确实会影响到代码的味道,除非您完全被这些对象和方法所束缚。

您可以从函数返回一个初始化对象,并使用GetType()和typeof对其进行测试。下面是一个例子(当然蒂姆的例子也适用)


你需要这样的东西:

public interface IPersonOrganization {
}
public class Peron : IPersonOrganization {
}
public class Organization : IPersonOrganization {
}

private IPersonOrganization GetPersonOrganization(bool isPerson) {
  if (isPerson) 
    return new Person();
  else
    return new Organization;
}

这里有一个方法;尽管这假设存在无参数构造函数:

using System;

namespace StackOverflow.Demos
{

    class Program
    {
        public static void Main(string[] args)
        {
            new Program();
            Console.ReadKey();
        }
        private Program()
        {

            Type type = GetPersonOrOrganisation(new Person());
            //object myInstance = GetInstanceOfType(type);
            var myInstance = GetInstanceOfType(type);
            Console.WriteLine(myInstance.ToString());

            type = GetPersonOrOrganisation(new Organization());
            myInstance = GetInstanceOfType(type);
            Console.WriteLine(myInstance.ToString());

        }
        private Type GetPersonOrOrganisation(object what)
        {
            return what.GetType();
        }
        private object GetInstanceOfType(Type type)
        {
            //return type.GetConstructor(new Type[] { }).Invoke(new object[] { });
            return Activator.CreateInstance(type);
        }
    }

    public class Person
    {
        public Person() { }
    }
    public class Organization
    {
        public Organization() { }
    }
}

这就是你的问题吗

public void Demo()
{
    var myInstance = Activator.CreateInstance((new Person()).GetType());
    Console.WriteLine(Test(myInstance));
}
private string Test(object x) //this is the method being called
{ 
    return string.Format("Object - {0}", x.ToString()); 
}
private string Test(Person x) //this is what you were hoping for
{ 
    return string.Format("Person - {0}", x.ToString()); 
}
private string Test(Organization x) 
{ 
    return string.Format("Org - {0}", x.ToString()); 
}
一个修复方法是(不推荐):

更好的解决方案是:

public interface ITestMethod { string Test();}
public class Person : ITestMethod
{
    public Person() { }
    public string Test() { return string.Format("Person - {0}", this.ToString()); }
}
public class Organization : ITestMethod
{
    public Organization() { }
    public string Test() { return string.Format("Org - {0}", this.ToString()); }
}

//...
public void Demo()
{
    var myInstance = Activator.CreateInstance((new Person()).GetType()) as ITestMethod;
    Console.WriteLine(myInstance.Test());
}
//...

那没有道理。变量的类型在编译时存在,在您知道将是什么之前。你想要一个界面。吹毛求疵,但“组织”拼写为“组织”,带“z”。@这取决于你的语言;en us同意你的观点,en gb同意user2005657。接得好。。。挑剔的人!:)拼写差异:难道你就不能使用
Activator.CreateInstance
?对于默认构造函数,没有太多的性能开销。@Romoku是的-刚刚测试过,你是对的-我以前没有玩过Activator,所以按照我知道的方式。然而,这使得我的解决方案与问题相同。除非bug在其他地方(即问题中用伪代码总结的方法中)?请参见我的备选答案-我根据两种解释给出了两个答案-上述方法用于获得预期类型的实例。然而,如果你的代码中已经存在这种情况,那么问题就在于你的代码如何处理这种类型——我的另一个答案展示了如何处理这种情况。
public void Demo()
{
    var myInstance = Activator.CreateInstance((new Person()).GetType());
    Console.WriteLine(Test(myInstance));
}
private string Test(object x) //redirect the call to the right method
{
    if (x is Person)
        return Test(x as Person);
    else
        return Test(x as Organization);
}
private string Test(Person x) { return string.Format("Person - {0}", x.ToString()); } //this is what you were hoping for
private string Test(Organization x) { return string.Format("Org - {0}", x.ToString()); }
public interface ITestMethod { string Test();}
public class Person : ITestMethod
{
    public Person() { }
    public string Test() { return string.Format("Person - {0}", this.ToString()); }
}
public class Organization : ITestMethod
{
    public Organization() { }
    public string Test() { return string.Format("Org - {0}", this.ToString()); }
}

//...
public void Demo()
{
    var myInstance = Activator.CreateInstance((new Person()).GetType()) as ITestMethod;
    Console.WriteLine(myInstance.Test());
}
//...