2

下面的代码可以很好地产生这个输出:

This is page one.
This is page two.

但是如何更改它以便 PageItem对象List<string>?

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.";

        }
    }
}
4

4 回答 4

8

我相信您可以使用接受参数输入的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.";

        }
    }
}
于 2009-11-09T16:50:32.123 回答
3

这样编译成功。我刚试过。

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" };

使代码成功运行。

您需要记住,反射方法总是null在找不到某些东西时返回,而不是引发异常。如果您的代码期望Type.GetType始终成功,那么您需要检查空值并引发您自己的异常,否则您将得到级联失败,因为空值通过其余代码传播。

于 2009-11-09T16:54:23.713 回答
1

查看 Activator.CreateInstance 的重载。您可以将构造函数传入对象数组中的一个。

于 2009-11-09T16:49:00.053 回答
1

我可以建议 Assembly.CreateInstance() 您可以使用此函数来创建指定程序集的实例。

于 2009-11-09T16:51:01.343 回答