如何在.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
是否有一种方法可以使这些属性成为用户选择的类型?
你可以让你的类泛型:
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)