[英]How can you instantiate an object with a string and send a parameter in C#?
下面的代码生成此输出正常:
This is page one.
This is page two.
但是如何更改它以便从List<string>
动态实例化PageItem对象?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestInstant
{
class Program
{
static void Main(string[] args)
{
List<string> pageItemsIdCodes = new List<string>() { "PageItem1", "PageItem2" };
PageItemManager pageItemManager = new PageItemManager(pageItemsIdCodes);
pageItemManager.DisplayMenu();
Console.ReadLine();
}
}
class PageItemManager
{
private Dictionary<string, BasePageItem> PageItemRecords = new Dictionary<string, BasePageItem>();
public PageItemManager(List<string> pageItemsIdCodes)
{
//manually
PageItemRecords.Add("PageItem1", new PageItem1(this));
PageItemRecords.Add("PageItem2", new PageItem2(this));
//HOW DO i DO THIS DYNAMICALLY:
//PSEUDO-CODE:
//foreach (string pageItemIdCode in pageItemsIdCodes)
//{
// Type t = Type.GetType(pageItemIdCode);
// //ERROR: Cannot implicitly convert type 'TestInstant.PageItemManager' to 'TestInstant.BasePageItem'
// BasePageItem pageItem = Activator.CreateInstance(t, new BasePageItem[] { this });
// PageItemRecords.Add(pageItemIdCode, pageItem);
//}
//Type t = Type.GetType(pageItemIdCode);
//ERROR: Cannot implicitly convert type 'object' to 'TestInstant.BasePageItem'.
//BasePageItem pageItem = Activator.CreateInstance(t); // Change constructor
//pageItem.PageItemManager = this; // Add SetMananger call to BasePageItem
//PageItemRecords.Add(pageItemIdCode, pageItem);
}
public void DisplayMenu()
{
foreach (var pageItemRecord in PageItemRecords)
{
Console.WriteLine(pageItemRecord.Value.Title);
}
}
}
class BasePageItem
{
public string Title { get; set; }
protected PageItemManager pageItemManager;
public BasePageItem(PageItemManager pageItemManager)
{
this.pageItemManager = pageItemManager;
}
}
class PageItem1 : BasePageItem
{
public PageItem1(PageItemManager pageItemManager)
: base(pageItemManager)
{
Title = "This is page one.";
}
}
class PageItem2 : BasePageItem
{
public PageItem2(PageItemManager pageItemManager)
: base(pageItemManager)
{
Title = "This is page two.";
}
}
}
我相信你可以使用Activator.CreateInstance来获取输入参数。
foreach (string pageItemIdCode in pageItemsIdCodes)
{
Type t = Type.GetTypeFromProgID(pageItemIdCode);
Object pageItem = Activator.CreateInstance(t, new object[]{this});
PageItemRecords.Add(pageItemIdCode, pageItem);
}
或者正如groo所说,只是投下它:
foreach (string pageItemIdCode in pageItemsIdCodes)
{
Type t = Type.GetTypeFromProgID(pageItemIdCode);
BasePageItem pageItem = (BasePageItem)Activator.CreateInstance(t, new object[]{this});
PageItemRecords.Add(pageItemIdCode, pageItem);
}
如果要返回实际类型,还可以执行以下操作:
foreach (string pageItemIdCode in pageItemsIdCodes)
{
Type t = Type.GetTypeFromProgID(pageItemIdCode);
BasePageItem pageItem = Activator.CreateInstance(t); // Change constructor
pageItem.SetMananger(this); // Add SetMananger call to BasePageItem
PageItemRecords.Add(pageItemIdCode, pageItem);
}
这是完整的工作示例:
using System;
using System.Collections.Generic;
using System.Text;
namespace TestInstant
{
class Program
{
static void Main(string[] args)
{
List<string> pageItemsIdCodes = new List<string>();
pageItemsIdCodes.Add("PageItem1");
pageItemsIdCodes.Add("PageItem2");
PageItemManager pageItemManager = new PageItemManager(pageItemsIdCodes);
pageItemManager.DisplayMenu();
Console.ReadLine();
}
}
class PageItemManager
{
private Dictionary<string, BasePageItem> PageItemRecords = new Dictionary<string, BasePageItem>();
public PageItemManager(List<string> pageItemsIdCodes)
{
//manually
//PageItemRecords.Add("PageItem1", new PageItem1(this));
//PageItemRecords.Add("PageItem2", new PageItem2(this));
foreach (string pageItemIdCode in pageItemsIdCodes)
{
Type t = Type.GetType("TestInstant."+pageItemIdCode);
BasePageItem pageItem = (BasePageItem)Activator.CreateInstance(t, new Object[] { this });
PageItemRecords.Add(pageItemIdCode, pageItem);
}
}
public void DisplayMenu()
{
foreach (BasePageItem pageItemRecord in PageItemRecords.Values)
{
Console.WriteLine(pageItemRecord.Title);
}
}
}
class BasePageItem
{
private string mTitle;
public string Title { get { return mTitle; } set { mTitle = value; } }
protected PageItemManager pageItemManager;
public BasePageItem(PageItemManager pageItemManager)
{
this.pageItemManager = pageItemManager;
}
}
class PageItem1 : BasePageItem
{
public PageItem1(PageItemManager pageItemManager)
: base(pageItemManager)
{
Title = "This is page one.";
}
}
class PageItem2 : BasePageItem
{
public PageItem2(PageItemManager pageItemManager)
: base(pageItemManager)
{
Title = "This is page two.";
}
}
}
这成功编译。 我刚尝试过。
foreach(string pageItemIdCode in pageItemsIdCodes) {
Type t = Type.GetType(pageItemIdCode);
BasePageItem pageItem = (BasePageItem) Activator.CreateInstance(t, new object[] { this });
PageItemRecords.Add(pageItemIdCode, pageItem);
}
然后它在运行时失败,因为pageItemIdCode
值不正确。 更改如下:
List<string> pageItemsIdCodes = new List<string>() { "TestInstant.PageItem1", "TestInstant.PageItem2" };
使代码成功运行。
您需要记住,当Reflection方法无法找到某些内容时,它总是返回null
,而不是引发异常。 如果您的代码期望Type.GetType
始终成功,那么您需要检查空值并引发自己的异常,否则您将获得级联故障,因为空值通过其余代码传播。
查看Activator.CreateInstance的重载。 您可以将对象数组中的构造函数传递给它们一个。
我可以建议Assembly.CreateInstance()您可以使用此函数来创建指定程序集的实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.