C # Создает экземпляр класса из String с интерфейсом - PullRequest
1 голос
/ 25 августа 2011

Я пытаюсь создать экземпляр класса на основе строки, которая будет извлечена из пользовательского интерфейса, а затем я хочу получить доступ к свойствам экземпляра класса.

Вотобзор того, что у меня пока есть -

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 ]

2 голосов
/ 26 августа 2011

Проблема заключается в том, как вы указываете имя вашего класса:

Сначала укажите пространство имен.Во-вторых, поскольку Arca является внутренним классом, вы должны использовать «+» вместо «.»

(...) = Exchange.DeriveExchange("MamdaAdapter.Exchange+Arca");
2 голосов
/ 25 августа 2011

Если ваш пользовательский интерфейс не отображает полное имя типа, вы обычно хотите, чтобы словарь связывал отображаемое имя с типом:

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
}
0 голосов
/ 26 августа 2011

Если искомый тип не определен в той же сборке, где выполняется Type.GetType, вы должны использовать AssemblyQualifiedName (что-то вроде MyNamespace.MyClass, MyAssembly, Version = 1.3.0.0, Culture = нейтральный, PublicKeyToken = b17a5c561934e089), даже FullName недостаточно.В противном случае вы можете сначала получить сборку, содержащую класс, а затем выполнить метод GetType класса Assembly.

0 голосов
/ 25 августа 2011

Я написал небольшое консольное приложение на 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;
        }
    }

}
...