如何在.NET中定义运行时的属性类型?

时间:2011-11-29 11:42:02

标签: c# .net types

在Winform应用程序中,我有一个包含2个属性的类,我希望用户能够选择这些属性的类型。

这是我到目前为止所做的:

具有属性的类:

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

用户可以使用带有DropDownList Style的Combobox选择属性的类型,其值为

System.String
System.Double
System.Int32
System.Boolean
System.DateTime 

有没有办法让这些属性成为用户选择的类型?

4 个答案:

答案 0 :(得分: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变量或(首选)使用一些返回键入的值作为对象的公共接口或基类。 / p>

答案 1 :(得分: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

答案 2 :(得分:1)

不,不是。一个类是静态编译的。不想在运行时更改静态类的属性。

但是,您可以通过字节码发射创建子类nd覆盖它。

答案 3 :(得分:0)

您可以使用is关键字

if (x.SearchColumn is Double)
{
}

另请参阅MSDN:Is (C# Reference)