C# 根据给定接口的字符串实例化类

发布于 2024-12-01 13:51:24 字数 1112 浏览 4 评论 0原文

我试图根据将从用户界面检索的字符串创建一个类的实例,然后我想访问该类实例的属性。

以下是我迄今为止所掌握的内容的概述 -

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());
        }
    }
}

更新: 现在,我收到一个异常,提示“值不能为空”,这对我来说意味着它无法根据提供的字符串创建类的实例 -

I am trying to make an instance of a class based on a string that will be retrieved from the User Interface, and then I want to access the properties of the instance of the class.

Here is an overview of what I have so far -

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());
        }
    }
}

UPDATE:
Right now, I'm getting an Exception that says the "Value cannot be null" which to me means that it is unable to create the instance of the class given the string provided -

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一紙繁鸢 2024-12-08 13:51:24

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

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

(...) = Exchange.DeriveExchange("MamdaAdapter.Exchange+Arca");

The problem here is how you specify the name of your class:

First, specify the namespace. Second, since Arca is an inner class you must use '+' instead of '.'

(...) = Exchange.DeriveExchange("MamdaAdapter.Exchange+Arca");
暖心男生 2024-12-08 13:51:24

假设您的 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
}

Assuming you UI doesnt expose the full type name, you typically want a dictionary to associate the display name to the type:

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

Then, you simply instantiate the new object:

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

   return Activator.CreateInstance(selectedType) as IExchange;
}

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

If the string is not known at compile time, you basically need to check for the existance of the type:

var type = Type.GetType(someString);

if(type != null)
{
    // Do Stuff
}
半世晨晓 2024-12-08 13:51:24

我编写了一个小型的 C# 控制台应用程序来模拟您的需求,测试正常,希望它有所帮助:

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

}

I wrote a small c# console application to simulate your need, tested ok, hope it helps:

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

}
转身泪倾城 2024-12-08 13:51:24

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

If the Type you are looking for is not defined in the same assembly that is executing Type.GetType you must use the AssemblyQualifiedName (something like MyNamespace.MyClass, MyAssembly, Version=1.3.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089), even the FullName is not enough. Otherwise you could first get the assembly containing the class and then execute the GetType method of the Assembly class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文