如何在.net运行时定义属性的类型

本文关键字:属性 类型 定义 运行时 net | 更新日期: 2023-09-27 18:15:59

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

这是我目前所做的:

类的属性:

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

用户可以使用下拉列表样式的组合框来选择属性的类型,该组合框的值如

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

是否有一种方法可以使这些属性成为用户选择的类型?

如何在.net运行时定义属性的类型

你可以让你的类泛型:

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变量,或者(首选)使用一些公共接口或基类来返回类型为对象的值。

有方法在运行时使用泛型使属性强类型,但我不确定它有多有用。这里有一个解决方案:

创建一个非强类型的接口,以方便与对象的交互:

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

不,没有。类是静态编译的。没有办法在运行时更改静态类的属性。

您可以创建一个子类并通过字节码发射覆盖它。

您可以使用is关键字

if (x.SearchColumn is Double)
{
}

参见MSDN: Is (c# Reference)