有如下方法:
public T GetList<T>(....)现在我在外面需要调用此方法 ,但在调用的时候,我需要动态指定T,我也知道T所在的程序集和类名。请问,如何调用?
List<??> a = GetList<??>(...);如上,问号处要动态指定,不允许写死,请问怎么写?谢谢!
public T GetList<T>(....)现在我在外面需要调用此方法 ,但在调用的时候,我需要动态指定T,我也知道T所在的程序集和类名。请问,如何调用?
List<??> a = GetList<??>(...);如上,问号处要动态指定,不允许写死,请问怎么写?谢谢!
不过,如果的是值类型,要装箱和拆箱,效率会差点.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace WindowsApplication2
{
public partial class Form1 : Form
{
public T GetList<T>(T t)
{
if (t is int)
MessageBox.Show("int " + t.ToString());
else if (t is float)
MessageBox.Show("float " + t.ToString());
else
MessageBox.Show("String " + t.ToString());
return t;
} public Form1()
{
InitializeComponent(); int i = 100;
float f = 123.4f;
String s = "a"; i = GetList(i);
f = GetList(f);
s = GetList(s);
}
}
}
list<接口> 吧.
list <接口> 吧.
-------------------------------
各T的属性完全不一样,所以不可能用接口实现 。
返回来的是object ,如果要返回的是Int和String ....你除非方法有个参数告诉object是什么...没有还真不知道有什么好办法.
{
if (DataSet == null || DataSet.Tables.Count < 0)
return null;
if (TableIndex > DataSet.Tables.Count - 1)
return null;
if (TableIndex < 0)
TableIndex = 0; System.Data.DataTable dt = DataSet.Tables[TableIndex];
IList<T> result = new List<T>();
for (int j = 0; j < dt.Rows.Count; j++)
{
T t = (T)Activator.CreateInstance(typeof(T));
PropertyInfo[] propertys = t.GetType().GetProperties();
foreach (PropertyInfo pi in propertys)
{
for (int i = 0; i < dt.Columns.Count; i++)
{ if (pi.Name.Equals(dt.Columns[i].ColumnName))
{
if (dt.Rows[j][i] != DBNull.Value)
pi.SetValue(t, dt.Rows[j][i], null);
else
pi.SetValue(t, null, null);
break;
}
}
}
result.Add(t);
}
return result;
}
{
if (t is int)
MessageBox.Show("int " + t.ToString());
else if (t is float)
MessageBox.Show("float " + t.ToString());
else
MessageBox.Show("String " + t.ToString());
return t;
}-------------------------------
我是动态加载插件的,插件是由其他人开发,需要用的时候装载进来,如果按你这样写就好办了,关键是现在根本不知道外面有多少种插件,各插件的数据是什么类型。
不客气得说,是你原来的思路有问题!
{
if (DataSet == null || DataSet.Tables.Count < 0)
return null;
if (TableIndex > DataSet.Tables.Count - 1)
return null;
if (TableIndex < 0)
TableIndex = 0; System.Data.DataTable dt = DataSet.Tables[TableIndex];
IList<T> result = new List<T>();
for (int j = 0; j < dt.Rows.Count; j++)
{
T t = (T)Activator.CreateInstance(typeof(T));
PropertyInfo[] propertys = t.GetType().GetProperties();
foreach (PropertyInfo pi in propertys)
{
for (int i = 0; i < dt.Columns.Count; i++)
{ if (pi.Name.Equals(dt.Columns[i].ColumnName))
{
if (dt.Rows[j][i] != DBNull.Value)
pi.SetValue(t, dt.Rows[j][i], null);
else
pi.SetValue(t, null, null);
break;
}
}
}
result.Add(t);
}
return result;
}
-----------------------------------------
此方法跟我们的数据持久层里用的方法一样,这种方法在外面调用的时候会指定类型的,所以跟我问的问题完全是两码事,谢谢!
不客气得说,是你原来的思路有问题!
-------------------------------------------
我们的接口已经定义过了。就是GetLIst<T>,具体,它只要扔LIST出来就行了,主程序里会去遍历,会根据插件字典去读需要用到的属性的。而各插件的数据,也就是T,是完全不一样,不做限定的。
如
插件->飞机,可能有两个属性,翅展长度,发动机数
插件->大葱,有属性,长度,产地
使用泛型符号T,是为了充分利用强类型检查带来的好处,包括编译期类型检查和代码提示。
而运行期才能知道T则失去了这些好处,这种情况还不如直接用非泛型的ArrayList,或使用接口。下面代码中的GetList(Type)体现了这种尴尬的实现。
public partial class Form1 : Form
{
public object GetList(Type type) //<--- object
{
MethodInfo mi = typeof(Form1).GetMethod("GetList");
MethodInfo gi = mi.MakeGenericMethod(type); //<---
return gi.Invoke(null, null);
} public static List<T> GetList<T>()
{
return new List<T>();
}}
如果要动态创建对象实例、获取属性之类的可以
T t = (T)Activator.CreateInstance(typeof(T));
PropertyInfo[] propertys = t.GetType().GetProperties();
所以重点应该是想好你这个方法要进行些什么操作,反射处理应该是必须的
使用泛型符号T,是为了充分利用强类型检查带来的好处,包括编译期类型检查和代码提示。
而运行期才能知道T则失去了这些好处,这种情况还不如直接用非泛型的ArrayList,或使用接口。下面代码中的GetList(Type)体现了这种尴尬的实现。C# code public partial class Form1 : Form { public object GetList(Type type) //<--- object { MethodInfo mi = typeof(Form1).GetMethod("GetList"); MethodInfo gi = mi.MakeGenericMethod(type); //<--- return gi.Invoke(null, null); } public static List<T> GetList<T>() { return new List<T>(); } }-----------------------------------------
这种办法是可以返回出来,但你这个跟我直接返回object又有什么不同呢?因为如果你返回object,那我在外面就要拆箱,如何将object又拆成List<??>呢?
如果要动态创建对象实例、获取属性之类的可以
T t = (T)Activator.CreateInstance(typeof(T));
PropertyInfo[] propertys = t.GetType().GetProperties();
所以重点应该是想好你这个方法要进行些什么操作,反射处理应该是必须的
--------------------------------------------
反射创建,获取属性,设置属性值这些我都知道,
关键是:List<??> a = GetList<??>,这个问号这里,我只知道程序集名和类名,如何实现这句话?只要实现了这句话,其他的问题都不是问题了。
现在需要把字典中:"UnknowClass"字符串“转”成一个 UnknowClass 类型,List <UnknowClass> a = GetList <UnknowClass >(...); 这样???
这个和接口实现理论一至!并且可以实现.
比如:
Class UnknowClass
{
public string DataName;//类型名称
public object DataObj;//数据
}
想用的时候,通过DataName来决定你想转成哪个数据.....
不可以转的,你如何根据DataName生成并执行以下语句?
List<"Dataname"> t = new List<"DataName">();
而且没了类型,反射也无力了。
你好!
如果你想通过反射来获取类型,然后指定泛型方法的话,似乎不可行。
因为通过反射只能获得Type实例,这个不能用来指定泛型方法啊!
--------------------------------------------------------------------------------
周雪峰
Sheng Jiang 蒋晟MVP2009年3月31日 2:19:340 投票
泛型是编译时的语法,运行时要使用泛型的话,需要用自动化代码编译器。
微软不建议使用泛型来做公开接口。--------------------------------------------------------------------------------
MSMVP VC++