TempoClick Ответов: 2

Как преобразовать/сопоставить строковое значение в/с именем класса


У меня есть несколько классов В а asp.net проект.

У меня также есть переменная, которая получает a class имя как string.

Мне нужно фактически сопоставить или преобразовать строковое значение переменной с соответствующим именем класса.

Что я уже пробовал:

Например, у меня есть классы как flollows:
class Customer
class Vendor
class Importer

и переменная:
var className;

Если className = "Vendor", Я хочу на самом деле сделать строку "поставщик" как Vendor класс.

каков самый простой способ сделать это?

2 Ответов

Рейтинг:
7

johannesnestler

С таким отражением, как это:

class Program
    {
        class Customer { }
        class Vendor { }
        class Importer { }
        static void Main(string[] args)
        {
            string strClassName = nameof(Importer); // Use Full typename
            if (strClassName == nameof(Importer))
            {
                Importer importerInstance = Activator.CreateInstance(typeof(Importer)) as Importer;
            }
            else if (strClassName == nameof(Vendor))
            {
                Vendor importerInstance = Activator.CreateInstance(typeof(Vendor)) as Vendor;
            }
            // ...
        }
    }


TempoClick

Спасибо за ответ. Как я могу избежать операторов if/else? У меня слишком много занятий!

johannesnestler

Это был всего лишь пример того, как использовать активатор. Вы могли бы сделать это вот так:

классная программа
{
класс поддержки { }
поставщик класса { }
импортер класса { }
static void Main(string[] args)
{
строка strClassName = "ConsoleApp10.Program+Customer"; // обратите внимание на + в полном имени типа (это потому, что я встроил ваш тип в класс "Program"в этом примере)

Сборка сборка = сборка.GetAssembly(typeof(Program)); // получить вашу сборку
Тип type = сборка.GetType(strClassName); // тип поиска внутри сборки
object objInstance = активатор.CreateInstance(тип);

Приставка.ReadKey();
// ...
}
}

TempoClick

В вашем примере я получу класс Customer через objInstance в качестве объекта. Что делать, если я хочу затем использовать метод GetNames() в классе Customer? Как я должен назвать это наличие объекта objInstance?

johannesnestler

снова используйте отражение или "динамическое", или приведение к реальному типу (проверьте с помощью оператора "is" или "as"). Могу ли я спросить, какова ваша "реальная" проблема (так почему же вы должны это делать), может быть, есть и другие решения - потому что решения, основанные на строках и тяжелом отражении, подвержены ошибкам и высокой производительности...

johannesnestler

новый пример:

классная программа
{
класс Customer { public void DoTheCustomerThing() { консоль.WriteLine("Клиент"); } }
класс Vendor { public void DoTheVendorThing() { } }
импортер классов { public void DoTheImporterThing() { } }
static void Main(string[] args)
{
строка strClassName = "ConsoleApp10.Program+Customer"; // обратите внимание на + в полном имени типа (это потому, что я встроил ваш тип в класс "Program"в этом примере)

Сборка сборка = сборка.GetAssembly(typeof(Program)); // получить вашу сборку
Тип type = сборка.GetType(strClassName); // тип поиска внутри сборки
object objInstance = активатор.CreateInstance(тип);

//использовать экземпляр
// 1. Вариант бросания
// ... (с оператором "is" )
if(objInstance is Customer customer)
{
покупатель.DoTheCustomerThing();
}
// 2. динамический (проверьте наличие ошибок во время выполнения! нет проверки компилятора!) каким-то образом вы должны знать, какой тип имеет экземпляр и какие методы доступны
пробовать
{
динамический dynInstance = objInstance;
династия.DoTheCustomerThing();
//dynInstance.CallAMethodThatIsNotAvailableLeadstoruntimebinderexception(); // это дает вам исключение
}
catch(RuntimeBinderException)
{
// Метод не существует в типе
}
// 3. повторное использование отражения
MethodInfo mi = тип.GetMethod("DoTheCustomerThing");
ми.Вызов(objInstance, нуль);

Приставка.ReadKey();
// ...
}

johannesnestler

так что в конце концов большой переключатель или (если-elseif chain) - это самое простое, но "уродливое" решение-если вам действительно нужно сделать что-то подобное (как я уже сказал, Возможно, есть другие/лучшие решения вашей первоначальной проблемы) Я бы остановился на "простом", потому что такой код всегда нарушает объектную ориентацию и "лучшую практику"...

Рейтинг:
19

TempoClick

Спасибо за ответ. Как я могу использовать методы класса после этого?

F-ES Sitecore

Используйте отражение для запроса методов\свойств, чтобы узнать, существуют ли они, и вы также можете вызвать их через отражение.

Если есть какая-то общность между вашими классами, то пусть они реализуют общий интерфейс и вызывают методы через интерфейс.