2011-11-29 91 views
2

在Winform應用程序中,我有一個包含2個屬性的類,我希望用戶能夠選擇這些屬性的類型。如何在.NET中定義運行時屬性的類型?

這是我迄今取得:

類具有的屬性:

static public class DataGridColumnData 
{ 
    public static object SearchColumn { get; set; } 
    public static object ResultColumn { get; set; } 
} 

而且用戶可以選擇屬性的使用與DropDownList的樣式的組合框具有像

值類型
System.String 
System.Double 
System.Int32 
System.Boolean 
System.DateTime 

有沒有辦法讓這些屬性成爲用戶選擇的類型?

+1

如何做你想要的用戶後使用此選擇類型?你想過濾一些數據嗎? –

+0

Ditto Wouter的評論 - 這些類型在編譯時最有用。在運行時,它不會有太大的區別。也就是說,你總是可以定義一個通用的包裝類DataGridColumnData,它繼承自另一個類,並用類型訪問器包裝訪問器,然後定義新的實例。但我不確定你會用那些你無法用對象版本來做的事情。 – Rup

+0

這些屬性將用於在DataGridView中創建列。並且從數據庫中提取的數據將存儲在綁定到DataGridView的List中,因此我可以使用這些屬性將數據庫數據轉換爲用戶選擇的類型。 – user850010

回答

2

有一些方法可以使用泛型在運行時強制類型化屬性,但我不確定它是多麼有用。這裏是一個解決方案兩種方式:

創建一個不強類型,以方便與對象交互的接口:

public interface IDataGridColumnData 
{ 
    object SearchColumnAsObject { get; set; } 
    object ResultColumnAsObject { get; set; } 
} 

創建通用類,允許在運行時創建強類型的版本(和代碼以及,當然),並實現該接口:

public class DataGridColumnData<TSearch, TResult> : IDataGridColumnData 
{ 
    public TSearch SearchColumn { get; set; } 
    public static TResult ResultColumn { get; set; } 
    public object SearchColumnAsObject 
    { 
     get { return SearchColumn; } 
     set { SearchColumn = (TSearch)value; } 
    } 
    public object ResultColumnAsObject 
    { 
     get { return ResultColumn; } 
     set { ResultColumn = (TResult)value; } 
    } 
} 

創建一個工廠方法,將製造類的強類型版本,它返回的類型對象的接口:

private static IDataGridColumnData GetDataGridColumnData(
    Type searchType, Type resultType) 
{ 
    var typedColumnDataType = typeof(DataGridColumnData<,>) 
      .MakeGenericType(new[] { searchType, resultType }); 
    return (IDataGridColumnData)Activator.CreateInstance(typedColumnDataType); 
} 

...並把它用:

IDataGridColumnData instance = GetDataGridColumnData(
    Type.GetType("System.Int32"), 
    Type.GetType("System.String")); 

// use the properties 
instance.SearchColumnAsObject = 42; // works well 
instance.SearchColumnAsObject = "42"; // throws exception 
0

可以使用is關鍵字

if (x.SearchColumn is Double) 
{ 
} 

參見MSDN:Is (C# Reference)

+1

他想設置SearchColumn的類型,而不是檢查它是什麼類型。 – MBen

+0

哦,我以爲OP只是想把任何對象放入屬性中,然後再決定對象是什麼類型。我認爲OP已經將「object」類型硬編碼爲「接受所有」類型的類型。一個適合任何東西的盒子,但是當你打開它時,你不知道里面的物體是什麼類型。 – Bazzz

1

沒有,療法不是。一個類是靜態編譯的。不要在運行時改變靜態類的屬性。

雖然你可以創建一個子類nd通過字節碼發射覆蓋它。

5

你可以讓你的類通用:

static public class DataGridColumnData<T> 
{ 
    public static T SearchColumn { get; set; } 
    public static T ResultColumn { get; set; } 
} 

然後,在你的代碼,你可以創建一個類所需的類型:

object myDataGridColumnData; 
if (userSelection == "String") { 
    myDataGridColumnData = new DataGridColumnData<string>(); 
} else if (userSelection == "Double") { 
    myDataGridColumnData = new DataGridColumnData<double>(); 
} ... 

需要注意的是,在技術上,DataGridColumnData<string>完全是一種不同於DataGridColumnData<int>,因此object是唯一常見的超類型。因此,爲了能夠在代碼中訪問myDataGridColumnData的值,可能需要使用dynamic變量或(首選)使用某個通用接口或基類,該接口或基類返回鍵入爲對象的值。

相關問題