gpt4 book ai didi

c# .NET 运行时对象类型

转载 作者:行者123 更新时间:2023-11-30 14:20:33 30 4
gpt4 key购买 nike

我需要创建一个对象的实例,该对象的类型将在运行时确定。对象的类型从 SQL 中提取并设置为字符串值。我在实例化它的时候还需要传递一些参数。参数的数量/类型每次都是相同的(至少现在是这样)。我需要用什么来完成这个,Activator.CreateInstance?任何帮助将不胜感激。

    private void StartScans(int scan_typeid, SqlDataReader drActiveServers)
{
string sql = "SELECT scan_typeclass from scan_types WHERE scan_typeid = " + scan_typeid.ToString();
sqlconn.Open();
SqlCommand cmd = new SqlCommand(sql, sqlconn);
SqlDataReader drScanClass = cmd.ExecuteReader(CommandBehavior.CloseConnection);

string scan_class = drScanClass["scan_typeclass"].ToString();

//Create object here

}

编辑:

Richard Berg 的解决方案在控制台应用程序中有效,但在上面的示例中无效,我转储了 scan_class 并验证了它是否获得了一个值,但是我一直收到此错误:

System.ArgumentNullException:值不能为空。参数名称:类型

这是我更新后的代码:

        try
{
string sql = "SELECT scan_typeclass from scan_types WHERE scan_typeid = " + scan_typeid.ToString();
sqlconn3.Open();
SqlCommand cmd = new SqlCommand(sql, sqlconn3);
SqlDataReader drScanClass = cmd.ExecuteReader();
drScanClass.Read();

string scan_class = drScanClass["scan_typeclass"].ToString();

var type = Type.GetType(scan_class);
var myObj = Activator.CreateInstance(type, scan_id, scan_name, interval, drActiveServers);

}
catch (Exception e)
{
string sSource = "SharedAuditSVC";
string sLog = "Application";
string sEvent = e.ToString();

if (!EventLog.SourceExists(sSource))
EventLog.CreateEventSource(sSource, sLog);

EventLog.WriteEntry(sSource, sEvent);
EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Warning, 0);

}

嗯,我认为它与范围相关,尽管我通过此方法调用我的自定义类没有成功。我会睡在上面..:)

作品:

WindowsServiceAudit WSA = new WindowsServiceAudit(scan_id, scan_name, interval, drActiveServers);

不起作用:

string scan_class = "WindowsServiceAudit";               

var type = Type.GetType(scan_class);
var myObj = Activator.CreateInstance(type, scan_id, scan_name, interval, drActiveServers);

最佳答案

是的,完全正确。

var type = Type.GetType(scan_class);
var myObject = Activator.CreateInstance(type, constructorArg1, constructorArg2, [...] );

// use myObject - you'll have to reflect on any properties that aren't derived from System.Object

编辑

如果构造函数是静态的或非公共(public)的,或者您传递的参数在构造函数的重载解析中造成歧义,那么您将需要使用 MethodInfo.Invoke() 而不是 Activator.CreateInstance()。

var scan_class = "WindowsServiceAudit";
var bindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
var constructorArgs = new object[] { scan_id, scan_name, interval, drActiveServers };
var constructorTypes = from p in constructorArgs select p.GetType();

var type = Type.GetType(scan_class);
var method = type.GetMethod(scan_class, bindingFlags, System.Type.DefaultBinder, constructorTypes.ToArray(), null);
var myObject = method.Invoke(null, bindingFlags, System.Type.DefaultBinder, constructorArgs, CultureInfo.CurrentCulture);

还要确保:

  1. 类型名称是完全限定的。反射对“使用”语句一无所知。
  2. 加载类型所在的程序集。如有必要,请使用 Assembly.Load()。

关于c# .NET 运行时对象类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1220428/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com