Рейтинг:
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
Используйте отражение для запроса методов\свойств, чтобы узнать, существуют ли они, и вы также можете вызвать их через отражение.
Если есть какая-то общность между вашими классами, то пусть они реализуют общий интерфейс и вызывают методы через интерфейс.