2013-08-27 215 views
1

我有100個類都具有相似的簽名方法,只是它們的內部定義不同。我將傳遞一個類名作爲字符串,我需要創建該類型的對象並調用方法。我知道我可以使用「Activator.CreateInstance」,但不確定在這種情況下究竟如何。例如,讓我說我有Calculator1到Calculator100的類我不知道如何根據類名稱字符串在第二行投射它。從字符串類名創建對象

ObjectHandle handle = Activator.CreateInstance("NameSpaceCalculator", "Calculator1"); 
    var Calculator = (Calculator1)handle.Unwrap(); 
+1

使用一個通用接口。 – SLaks

+0

你*不會*施放它。除非這些類都共享一個接口,否則投射甚至沒有意義。你究竟想要做什麼? – aquinas

+0

你不能這樣做,除非觸摸某種'動態'。但是,仍然可以使用「反射」來訪問創建的對象的成員,而不必將其轉換爲所需的類型。 –

回答

1

這對我的作品,但接口將是這樣做的更好的方法:

void Main() 
{ 
    var x = CreateClass("A"); 
    x.Unwrap(); 
} 

public BaseC CreateClass(string typeName) 
{ 
    var type = Type.GetType(string.Format("MyNamespace.{0}",typeName); 
    return (BaseC)Activator.CreateInstance(type); 
} 


public class A : BaseC 
{ 
    public override void Unwrap() 
    { 
     Console.WriteLine("A"); 
    } 
} 

public class B : BaseC 
{ 
    public override void Unwrap() 
    { 
     Console.WriteLine("B"); 
    } 
} 

public class BaseC 
{ 
    public virtual void Unwrap() 
    { 
     Console.WriteLine("BaseC"); 
    } 
} 


//// Here is the approach with an Interface (note that overrides and virtual declaration needed. 





void Main() 
    { 
     var x = CreateClass<IBase>("MyNamespace","A"); 
     x.Unwrap(); 
    } 

    public T CreateClass<T>(string classNamespace, string typeName) where T : class 
    { 
     var type = Type.GetType(string.Format("{0}.{1}",classNamespace, typeName)); 
     return (T)Activator.CreateInstance(type); 
    } 


    public class A : IBase 
    { 
     public void Unwrap() 
     { 
      Console.WriteLine("A"); 
     } 
    } 

    public class B : IBase 
    { 
     public void Unwrap() 
     { 
      Console.WriteLine("B"); 
     } 
    } 

    public interface IBase 
    { 
     void Unwrap(); 
    } 
+0

我使用了薩達姆的CreateClass方法。它完美地工作,但在你的Baseclass中,Method必須是虛擬的,所以調用子方法。 – Dannydust

+0

我也使用了一個接口。它更好,因爲你不需要覆蓋和虛擬方法。 – Dannydust

1

您既可以使用一個共同的接口定義的Unwrap()方法和流延到該接口,或者你可以使用反射來找到Unwrap方法,並調用它。

除非你在運行時加載的組裝和在它不能使用編譯時引用的界面,反射是這種情況下緩慢和過於複雜的我會使用第一個選項。

+0

C#反射其實很快。 –

+0

'解開()''是不是ObjectHandle'他的計算器類的一部分,我不知道爲什麼有強制轉換爲'ObjectHandle'第一plave –

+0

@ sa_ddam213我現在看到。我仍然認爲編寫一個通用接口將是最好的解決方案。 – TheEvilPenguin

1

Perhap你可以先得到正確的類型,然後創建實例。

public CalculatorBase CreateClass(string typeName) 
{ 
    var type = Type.GetType(string.Format("NameSpaceCalculator.{0}",typeName)); 
    return (CalculatorBase)Activator.CreateInstance(type); 
} 
+0

我試過這個,但它調用了CalculatorBase類方法而不是那個特定的類。 – Multicaster