1

型を返すメソッドがあるとします:

private Type GetPersonOrOrganisation(someParameter)
{
  either return Person type or Organisation type
}

次に、このメソッドを呼び出します。

Type type = GetPersonOrOrganisation(someParameter);

次に、返された型の新しいインスタンスを作成しようとします。

var newContact = Activator.CreateInstance(type);

私が残したのは、 newContact がオブジェクト型であるということです。私が望んでいたのは、GetPersonOrOrganisation から返されたものに応じて、newContact を Person または Organization のいずれかのタイプにすることでした。

newContact キャストを正しいタイプに変換する方法を知っている人はいますか?

4

5 に答える 5

1

関数から初期化されたオブジェクトを返し、GetType() と typeof を使用してテストできます。以下は一例です (確かに、Tim の例も同様に機能します)。

public class Person
{
}
public class Organization
{
}

class Program
{
    // Generate a Person if i == true or Organization if i == false
    static object GetPersonOrOrganization(bool i)
    {
        if (i == true)
        {
            return new Person();
        }
        else
        {
            return new Organization();
        }
    }

    static void Main(string[] args)
    {
        var p = GetPersonOrOrganization(true); // Generates a Person.

        if (p.GetType() == typeof(Person))
        {
            Console.WriteLine("Person!"); // This prints.
        }
        else
        {
            Console.WriteLine("Organization");
        }

        var o = GetPersonOrOrganization(false); // Generates an Organization.

        if (o.GetType() == typeof(Person))
        {
            Console.WriteLine("Person!");
        }
        else
        {
            Console.WriteLine("Organization!"); // This prints.
        }

        Console.ReadLine();
    }
}
于 2013-03-13T03:06:30.227 に答える
1

次のようなものが必要です。

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;
}
于 2013-03-13T03:08:49.837 に答える
1

これには間違いなくコードの匂いがします。しかし、おそらくそれを回避するいくつかの方法があります。

個人と組織の両方と同じ方法でやり取りする場合は、両方が実装するインターフェイスを検討することをお勧めします。または、特定のシナリオに応じて、基本クラスかもしれません。

それを超えて、提案を行うためには、おそらくあなたがその後何をしようとしているのかが必要です. インターフェイス (またはその他の基本クラス) がなければ、これらの型のいずれかになることができるオブジェクトを 1 つ持つことはできません。現在、それらが共通しているのはオブジェクトだけです。

シナリオに応じて、似たようなことをいくつか行うことができますif (newContact is Person) { } else if (newContact is Organisation) { }が、それらのオブジェクトとメソッドをそのままにしておくことが絶対にない限り、それは実際にはコードの匂いに陥っています。

于 2013-03-13T03:06:14.693 に答える
0

これはあなたが抱えている問題ですか?

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()); 
}

1つの修正はこれです(推奨されません):

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());
}
//...
于 2013-03-13T04:01:26.587 に答える
0

これが 1 つの方法です。ただし、これはパラメーターなしのコンストラクターが存在することを前提としています。

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() { }
    }
}
于 2013-03-13T03:17:21.027 に答える