在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
有没有办法让这些属性成为用户选择的类型?
答案 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)