2013-03-13 54 views
1

說我有一個返回類型的方法後,返回類型的新實例:創建一個實例如何將它轉換爲創建的類型

var newContact = Activator.CreateInstance(type); 

我留下的是newContact是類型對象。我想要的是newContact屬於Person或Organization類型,具體取決於GetPersonOrOrganisation返回的內容。

有誰知道如何將newContact轉換爲正確的類型?

+1

這是沒有意義的。變量的類型在編譯時存在,然後才能知道該變量是什麼。你想要一個界面。 – SLaks 2013-03-13 02:58:12

+0

Nitpicking,但「組織」拼寫爲「組織」,帶有「z」。 – Inisheer 2013-03-13 02:58:34

+0

@Inisheer取決於你的語言; en-us與你同意,en-gb同意user2005657。 – JohnLBevan 2013-03-13 03:03:40

回答

1

這絕對有一些代碼味道。但也許有一些解決方法。

如果您要以相同的方式與它們進行交互,您可能需要考慮人員和組織都實施的界面。或者可能是一個基類,具體取決於你的具體情況。

除此之外,我們可能需要您以後嘗試做的事情,以便能夠提出建議。沒有接口(或其他基類),你不能有一個可以是這兩種類型的對象。他們目前唯一共同的東西就是對象。

根據你的情況,你可以做一些不同的事情,比如if (newContact is Person) { } else if (newContact is Organisation) { }或類似的東西,但是這真的會進入代碼的氣味,除非你完全堅持這些對象和方法。

1

您可以從該函數返回一個初始化對象,並使用GetType()和typeof對其進行測試。下面是一個例子(當然,蒂姆的例子也會起作用)。

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

您需要somethign這樣的:

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; 
} 
0

這裏有一種方法;儘管這假定存在無參數構造函數:

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() { } 
    } 
} 
+0

難道你剛剛使用過'Activator.CreateInstance'嗎?對於默認的構造函數,沒有太多的性能開銷。 – Romoku 2013-03-13 03:24:53

+0

@Romoku yup - 剛剛測試過,你說得對 - 在我知道的方式之前,我沒有用Activator玩過。 。 。但是,這使得我的解決方案與問題相同。除非這個錯誤是在其他地方(即在問題中用僞代碼概括的方法中)? – JohnLBevan 2013-03-13 03:26:44

+0

請參閱我的備選答案 - 我已經根據兩種解釋給出了兩個答案 - 上述獲得預期類型實例的作品。但是,如果這已經在你的代碼中工作,那麼你的代碼如何處理這種類型就是問題 - 我的另一個答案顯示瞭如何處理這種情況。 – JohnLBevan 2013-03-13 04:03:16

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

一個補丁修復是這樣的(不推薦):

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()); 
} 
//... 
相關問題