现有两个类class1和class2,两个类中各有static的meth()方法。OK,现在index.cs文件中需要对刚才两个类的静态方法,进行动态调用。如何做?请不要告诉我,直接用class1.meth()来调用,这个地球人都知道。因为刚才举的只是两个类,但事实上我的项目中有上百个这样的类,需要动态来直接判断,动态直接调用。在网上找到这样一段代码,据说是动态类名创建实例的,代码可以通过编译,但是不知道如何调用到方法?
public object GetInstanceByName( string className )
{
object obj;
try
{
obj = Activator.CreateInstance( Type.GetType( className ) );
}
catch( Exception e )
{
throw new Exception( "动态创建实例失败 \n\n=> " + className , e );
}
return obj;
}还有,在网上搜索了下,好象可以用反射机制来做?但搜索到的文章都比较复杂难懂,希望有个高人按照我上面的要求,给几句关键代码。谢谢!
public object GetInstanceByName( string className )
{
object obj;
try
{
obj = Activator.CreateInstance( Type.GetType( className ) );
}
catch( Exception e )
{
throw new Exception( "动态创建实例失败 \n\n=> " + className , e );
}
return obj;
}还有,在网上搜索了下,好象可以用反射机制来做?但搜索到的文章都比较复杂难懂,希望有个高人按照我上面的要求,给几句关键代码。谢谢!
解决方案 »
- 正则的高手来帮下忙
- com组件技术
- ClientScript.RegisterStartupScript中斜杠的问题
- c# IP打印
- C#怎么实现窗体最小化隐藏?
- c#2.0连接Oracle9i所引发Error while trying to retrieve text for error ORA-12541的问题。
- .net开发sns获取hotmail联系人列表,post用户信息过去时,需要什么样的格式?
- C# 行多选 各路神指导一下小弟
- 为什么CheckedListBo.SelectionMode不能选择MultiSimple/MultiExtended?
- 简单问题,十进制转十六进制?
- 怎样将SQL语句转化成二进制数据进行传输
- 结构体的初始化问题
System.Reflection.Assembly.Load(string assemblyString)
System.Reflection.Assembly.LoadFrom(string assemblyFile) 当dll在特殊的路径
获取类型:
System.Object.GetType()
System.Reflection.Assembly.GetType(string name)
获取方法的实例对象:
System.Type.GetMethod(string name)
根据实例对象执行方法:
System.Reflection.MethodBase.Invoke(object obj, object[] parameters)
http://blog.csdn.net/knight94/archive/2006/04/10/657527.aspx
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void Form1_Load(object sender, EventArgs e)
{
Test();
} private void Test()
{
Type type = Type.GetType("TestStatic.A");
MethodInfo mi = type.GetMethod("Test");
object o = mi.Invoke(null, new object[] { "123" });
}
}
public class A
{
public static string Test(string a)
{
Console.WriteLine("A.Test() is run;"+a);
return a;
}
}
}
interface IWay
{
public virtual Meth();
}所有的类都从上面接口派生。
public IWay GetInstanceByName( string className )
{
IWay obj;
try
{
obj = (IWay)Activator.CreateInstance( Type.GetType( className ) );
}
catch( Exception e )
{
throw new Exception( "动态创建实例失败 \n\n=> " + className , e );
}
return obj;
}
IWay iway = GetInstanceByName(...);
iway.Meth();
在2005中一直报错未将对象引用设置到对象的实例。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。 异常详细信息: System.NullReferenceException: 未将对象引用设置到对象的实例。源错误:
行 25: {
行 26: Type type = Type.GetType("testGetClass.A");
行 27: MethodInfo mi = type.GetMethod("Test");//这句老出错
行 28: object o = mi.Invoke(null, null);
行 29: }
行 27: MethodInfo mi = type.GetMethod("Test");//这句老出错
行 28: object o = mi.Invoke(null, null);我的文章没说明吗,你需要在使用的时候加上BindingFlags说明,例如
object objReturn = yourType.InvokeMember(
"Test",
BindingFlags.DeclaredOnly |
BindingFlags.Public |
BindingFlags.Static | BindingFlags.InvokeMethod,
null,
null,
new object[]{ yourpara } );
而且,我不是用winForm,而是asp.net。在VS2005中新建一个asp.net项目,类文件都没有命名空间的呀!如何办?
而且,我不是用winForm,而是asp.net。在VS2005中新建一个asp.net项目,类文件都没有命名空间的呀!如何办?对于反射来说,主要是获得Type,你既然不需要加载Assembly,就可以把这部分省掉。反射对于winform和asp.net来说没有区别。如果没有命名空间,你在获得类型的时候不加上即可。
Type type = typeof( yourClassName );
public class A
{
public static void Test()
{
}
}//Call
Type type = typeof( A );
但是,关键是我现在想通过字符串来动态调用类,你明我的意思么?而不是通过类名来知道字符串,请指教!
Assembly assembly = Assembly.GetExecutingAssembly();
Type type = assembly.GetType( "A" );
Class2, App_Code.ps5u79wb, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null因此,你可以先用typeof(YourClass)查看后缀是什么,然后再用Type.GetType(YourClass+后缀)
tmp = tmp.Substring(tmp.IndexOf(","));
Type t = Type.GetType("Class2" + tmp);t.InvokeMember("MethodName", BindingFlags.InvokeMethod | BindingFlags.Static, null, null, null);
tmp = tmp.Substring(tmp.IndexOf(","));
Type t = Type.GetType("Class2" + tmp); t.InvokeMember("Write", BindingFlags.InvokeMethod | BindingFlags.Static|BindingFlags.Public, null, null, null);
我发现还是有很多人不理解我的需要,zjlion(晴海) 的代码正合我意!大家请先运行他的代码,我要的是他的效果!但是,现在新的问题出来了:在VS2005上新建一个ASP.Net项目却无法运行他的代码(现在我估计是2005里没有命名空间所致的),明白了吗?请高人们指点!在指点前,请先运行晴海的代码。
namespace TestStatic
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void Form1_Load(object sender, EventArgs e)
{
Test();
} private void Test()
{
Type type = Type.GetType("TestStatic.A");
MethodInfo mi = type.GetMethod("Test");
object o = mi.Invoke(null, new object[] { "123" });
}
}
public class A
{
public static string Test(string a)
{
Console.WriteLine("A.Test() is run;"+a);
return a;
}
}
}
{ //直接对 _country_id 写值,不引发 country_id 的 Set 函数。
Type myType = ClassInstance.GetType();
FieldInfo myFieldInfo = myType.GetField(ControlName,BindingFlags.NonPublic|BindingFlags.Public|BindingFlags.Instance);
if(myFieldInfo != null)
{
try
{
myFieldInfo.SetValue(ClassInstance, Value);
object asdf = myFieldInfo.GetValue(ClassInstance); //这是读取值的方法,不引发 get
return true;
}
catch //(Exception e)
{
//MessageBox.Show(e.Message);
}
}
return false;
}
{
if (this.ActiveMdiChild == null)
return; Type t = ActiveMdiChild.GetType();
Assembly assembly = Assembly.GetAssembly(t);
MethodInfo method = t.GetMethod(MothodName, BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.Instance | BindingFlags.Static); if (method == null)
return; t.InvokeMember(MothodName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.Instance | BindingFlags.Static, null, ActiveMdiChild, null);
}
{
protected void Page_Load(object sender, EventArgs e)
{
Test("A");
//Test("B");
} private void Test(string ClassName)
{
Assembly assembly = Assembly.GetExecutingAssembly();
Type type = assembly.GetType(ClassName);
string result = (string)type.InvokeMember("Test",BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, null);
Response.Write(result);
}
}public class A
{
public static string Test()
{
return "Call Class A";
}
}public class B
{
public static string Test()
{
return "Call Class B";
}
}
可是,你的代码能编译成功,并不能运行成功!不知你是否有测试过才发上来的?出错原因:未将对象引用设置到对象的实例。出错的代码是:string result = (string)type.InvokeMember("Test", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, null);
行 25: Response.Write(result);
行 26: }
{
protected void Page_Load(object sender, EventArgs e)
{
this.InvokeMethod("Class1", "WriteString", null);
this.InvokeMethod("Class2", "WriteString", new object[] { "AAAAAA"});
} private void InvokeMethod(string className, string methodName,object[] paras)
{
string tmp = typeof(Class1).AssemblyQualifiedName;
tmp = tmp.Substring(tmp.IndexOf(","));
Type t = Type.GetType(className + tmp);
t.InvokeMember(methodName, BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public|BindingFlags.NonPublic, null, null, paras);
}
}public class Class1
{
private static void WriteString()
{
System.Web.HttpContext.Current.Response.Write("This is Class1");
}
}
public class Class2
{
public static void WriteString(string s)
{
System.Web.HttpContext.Current.Response.Write("This is Class2: "+s);
}
}
string methodName = "Test"; Assembly a = Assembly.Load("App_Code");
Type t = a.GetType(className);
MethodInfo mi = t.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public);
if (mi != null)
mi.Invoke(null,null);