1

我正在尝试基于将从用户界面检索到的字符串创建一个类的实例,然后我想访问该类实例的属性。

这是我迄今为止所拥有的概述 -

namespace MamdaAdapter
{
    public interface IExchange
    {
        string GetTransport();
    }
}


namespace MamdaAdapter
{
    public class Exchange
    {
        public class Arca : IExchange
        {
            private const string _Transport = "tportname";

            public string GetTransport()
            {
                return _Transport;
            }
        }


        public static IExchange DeriveExchange(string ExchangeName)
        {
            IExchange SelectedExchange = (IExchange)Activator.CreateInstance(Type.GetType(ExchangeName));

            return SelectedExchange;
        }
    }
}



namespace MyUserInterface
{
    public class MainForm
    {
        private void simpleButton1_Click(object sender, EventArgs e)
        {
            IExchange SelectedExchange = Exchange.DeriveExchange("Exchange.Arca");

            Console.WriteLine(SelectedExchange.GetTransport());
        }
    }
}

更新: 现在,我收到一个异常,上面写着“值不能为空”,这对我来说意味着它无法在给定提供的字符串的情况下创建类的实例 -

4

4 回答 4

2

这里的问题是如何指定类的名称:

首先,指定命名空间。其次,由于 Arca 是一个内部类,因此您必须使用 '+' 而不是 '.'

(...) = Exchange.DeriveExchange("MamdaAdapter.Exchange+Arca");
于 2011-08-25T21:42:36.320 回答
2

假设您的 UI 没有公开完整的类型名称,您通常需要一个字典来将显示名称与类型相关联:

Dictionary<string, Type> _associations = new Dictionary<string, Type>(); 

然后,您只需实例化新对象:

if(_associations.ContainsKey(someString))
{
   Type selectedType = _associations[someString];

   return Activator.CreateInstance(selectedType) as IExchange;
}

throw new ApplicationException("No type defined for that string yo");

如果在编译时字符串是未知的,则基本上需要检查类型的存在:

var type = Type.GetType(someString);

if(type != null)
{
    // Do Stuff
}
于 2011-08-25T18:27:59.320 回答
0

如果您要查找的类型未在执行 Type.GetType 的同一程序集中定义,则您必须使用 AssemblyQualifiedName(类似于 MyNamespace.MyClass、MyAssembly、Version=1.3.0.0、Culture=neutral、PublicKeyToken=b17a5c561934e089),甚至FullName 是不够的。否则,您可以先获取包含该类的程序集,然后执行该程序集类的 GetType 方法。

于 2011-08-25T21:39:40.640 回答
0

我写了一个小的c#控制台应用程序来模拟你的需求,测试ok,希望对你有帮助:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MamdaAdapter;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            IExchange SelectedExchange = Exchange.DeriveExchange("MamdaAdapter.Arca");
            Console.WriteLine(SelectedExchange.GetTransport());
        }
    }
}

namespace MamdaAdapter
{
    public interface IExchange
    {
        string GetTransport();
    }
}


namespace MamdaAdapter
{
    public class Arca : IExchange
    {
        private const string _Transport = "tportname";

        public string GetTransport()
        {
            return _Transport;
        }
    }
}

namespace MamdaAdapter
{
    public class Exchange
    {
        public static IExchange DeriveExchange(string ExchangeName)
        {
            IExchange SelectedExchange = (IExchange)Assembly.GetAssembly(typeof(IExchange)).CreateInstance(ExchangeName, false, BindingFlags.CreateInstance, null, null, null, null);
            return SelectedExchange;
        }
    }

}
于 2011-08-25T19:04:31.343 回答