2014-11-04 54 views
0

我有一些類與以下模式:從裝配合格的名稱創建對象實例,並得到屬性值

namespace MyCompany.MyApplication.ReportingClasses 
{ 
public class ReportingClassName 
{ 
    public string HTMLReportString {get; private set;} 

    ReportingClassName() 
    { 
     // Use linq to generate report; 
     // Populate gridview, pass object to function which returns HTMLString; 
     // set HTMLReportString property; 
    } 

} 
} 

每個類都保存根據報告不同的LINQ查詢。我想從一個下拉框中的報表列表中動態加載這個類。我存儲AsseblyQualifiedName以及一個顯示名稱來填充DDL。我根據我所見過的帖子使用了反思,但我似乎無法表現出我想要的;

string myAssembly = "AssemblyName"; // This is static; 
string myClass = "AssemblyQualifiedName"; // This value from DDL; 
var myObject = Activator.CreateInstance(AssemblyName, AssemblyQualifiedName); 

string propertyValue = myObject.HTMLReportString; 

"UpdatePanelID".InnerHTML = propertyValue; 

我試圖完成什麼?

+1

前四行很簡單 - 將'var myObject'改爲'dynamic myObject',它應該沒問題。我不知道你想用最後一行做什麼,但... – 2014-11-04 16:05:19

+0

通常會重複的http://stackoverflow.com/questions/10338018/how-to-get-a-property-value-使用反射,但現在使用'dynamic'是這種特殊情況的更好選擇。 – 2014-11-04 16:19:31

回答

2

除了dcastro答案(這很好),我想建議第三個解決方案,它看起來更清潔:因爲「ReportingClassName」是你自己的代碼,你可以修改它,使其實現一個接口,它提供了什麼您需要:

namespace MyCompany.MyApplication.ReportingClasses 
{ 
public interface IReporting 
{ 
    string HTMLReportString {get;}  
} 

public class ReportingClassName : IReporting 
{ 
    public string HTMLReportString {get; private set;} 

    ReportingClassName() 
    { 
     // Use linq to generate report; 
     // Populate gridview, pass object to function which returns HTMLString; 
     // set HTMLReportString property; 
    } 

} 
} 


string myAssembly = "AssemblyName"; // This is static; 
string myClass = "AssemblyQualifiedName"; // This value from DDL; 
var myObject = Activator.CreateInstance(AssemblyName, AssemblyQualifiedName); 

string propertyValue = ((IReporting)myObject).HTMLReportString; // Thanks to the interface, myObject provides HTMLReportString and it doesn't need reflection neither "dynamic". 

"UpdatePanelID".InnerHTML = propertyValue; 

對於最後一部分,你也可以這樣做:

string propertyValue; 
var myReport = myObject as IReporting 
if(myReport != null) 
{ 
    propertyValue = myReport.HTMLReportString; 
} 
else 
{ 
    // Handle the error 
} 

只是要更安全。

+2

+1,我忘了提這個。如果你可以修改這些類,使它們都實現一個通用的接口。 – dcastro 2014-11-04 16:37:03

+0

謝謝dcastro,我確實實現了所有對象的通用接口。這也教會了我很多關於Interfaces的有用性,所以這很棒。理查德,我標記這個答案是正確的,但有一個疏忽,(IReporting)myObject應該是(IReporting)myObject.Unwrap()。一旦我添加該方法,它就像廣告一樣工作!爲了反映這種變化,我編輯了您的回覆,以便將整個解決方案包含在回覆的正文中而不是評論中。我感謝所有的幫助! – UncleJasper75 2014-11-04 17:29:49

+0

「Unwrap()」?這是從哪裏來的? Activator.CreateInstance返回給定類型的一個實例。在這種情況下,Unwrap沒有任何意義。我不確定要理解你在說什麼。但最重要的是你得到了你想要的東西。 – AFract 2014-11-04 17:37:43

2

myObject類型爲object,所以顯然它沒有任何名爲HTMLReportString的屬性。

既然你不知道的myObject在編譯時的類型,你就必須要麼:

  1. 使用反射來調用屬性

    string value = (string) myObject.GetType() 
               .GetProperty("HTMLReportString") 
               .GetValue(myObject); 
    
  2. 使用動態類型

    dynamic myObject = //... 
    string value = myObject.HTMLReportString; 
    
+0

這兩種情況在IL之間有差異嗎? – Dialecticus 2014-11-04 16:32:58

+0

@Dialecticus是的,第二個代碼實際上只會在運行時由[DLR](http://msdn.microsoft.com/en-us/library/dd233052(v = vs.110).aspx)進行編譯。我不確定哪個性能最好,你必須自己測試一下。 – dcastro 2014-11-04 16:35:56

相關問題