簡體   English   中英

如何使用字符串實例化對象並在C#中發送參數?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM