Получить тип класса по его имени

311
06 апреля 2017, 16:43

Как получить тип класса по его имени?

 class Program
{
    static void Main<T>(string[] args)
    {
        string className = "MyClass";
        var myClassType = Activator.CreateInstance(Type.GetType(className));
        var res = method<myClassType>();
    }
    public static List<T> method<T>()
    {
        return new List<T>();
    }
}
public class MyClass
{
    public string anyString { get; set; }
    public int anyInt { get; set; }
}
Answer 1

Красивым способом это не сделать, нужно использовать reflection и MakeGenericMethod:

string className = "ConsoleApplication1.MyClass";
var myClassType = Type.GetType(className);
var method = typeof(Program).GetMethod("method", BindingFlags.Static | BindingFlags.Public);
var genericMethod = method.MakeGenericMethod(myClassType);
// вернет список нужного типа - List<MyClass>
dynamic list = genericMethod.Invoke(null, null);
Answer 2

Activator отдаст Вам ссылку типа object на созданный объект класса по полному квалифицированному имени класса:

Type type = Type.GetType("ConsoleApplication17.MyClass");
object instance = Activator.CreateInstance(type);

Если Вы хотите обращаться к методам и полям объекта класса напрямую, то Вам нужно будет в явном виде указать конкретный тип. Для этого можно использовать, например, безопасное приведение типа:

var propertyValue = (instance as MyClass)?.anyInt;

Если Вы не хотите явно указывать тип в коде, то можете воспользоваться механизмом динамической типизации:

try
{
     dynamic dynamicInstance = instance;
     var propertyValue = dynamicInstance.anyInt
}
catch(RuntimeBinderException ex)
{
     Console.WriteLine("Wrong type specified: " + ex.Message);
}

Обратите внимание на обработку RuntimeBinderException.

Answer 3

Для получения типа по имени нужно дописывать пространство имен, а лучше использовать полное имя с указанием имени сборки.

Получить тип лучше из сборки. Предварительно её загрузив. Для .Net Core это выглядит так

static Assembly LoadAssembly(string fileName)
    {
        var Dir = AppContext.BaseDirectory;
        string path = Path.Combine(Dir, fileName);
        Assembly assembly = null;
        if (File.Exists(path))
        {
            try
            {
                var asm = System.Runtime.Loader.AssemblyLoadContext.GetAssemblyName(path);
                assembly = Assembly.Load(asm);
            }
            catch (Exception)
            {
                assembly = System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromAssemblyPath(path);
            }
        }
        return assembly;
    }

Ну а из сборки можешь получить и тип используя GetType

Посмотри здесь .Net Core, AppDomain, WCF, RPC маршалинг по Tcp/Ip свой велосипед

Там и поиск типа, методов с параметрами по умолчанию, параметрами массивами, Дженерик методами, методов расширений в том числе Linq, делегатов, объектов поддерживающие IDynamicMetaObjectProvider (DynamicObject,ExpandoObject,JObject). В том числе поиск дженерик метода с автовыводм типа по параметрам

Например там реализован динамический вызов дженерик метода

// Test Generic Method с параметрами по умолчанию 
    //public string GenericMethodWithDefaulParam<K, V>(Dictionary<K, V> param1, K param2, int param3 = 4, string param4 = "Test")
    var @Int32 = wrap.GetType("System.Int32");
    resGM = TO.GenericMethodWithDefaulParam(dict, 99);
    Console.WriteLine("Вызов дженерик метода с автовыводом  типов " + resGM);
    resGM = TO.GenericMethodWithDefaulParam(pp(@Int32, "System.String"), dict, 99);
    Console.WriteLine("Вызов дженерик метода с аргументами типов " + resGM);

    // Test Generic Method с параметрами массивом
    // public string GenericMethodWithParams<K, V>(Dictionary<K, V> param1, K param2, params string[] args)
    resGM = TO.GenericMethodWithParams(dict, 99, "First", "Second");
    Console.WriteLine("Вызов дженерик метода с автовыводом  типов " + resGM);

Где TO это динамик вызывающий метод по Tcp/IP, но его можно приязать к типу и вызвать методы локально. Просто для поиска метода из-за перегрузок, дефолтных параметрах, параметрах массивов не всегда простая задача

Для обычного .Net поиск сборки выглядит так. Сразу прошу прощения за Руслиш.

 private static Type НайтиТип(string type)
        {
            Type result = Type.GetType(type, false);
            if (result != null)
            {
                return result;
            }
            foreach (System.Reflection.Assembly tmpAasembly in
System.AppDomain.CurrentDomain.GetAssemblies())
            {
                result = tmpAasembly.GetType(type);
                if (result != null)
                {
                    return result;
                }
            }
            return null;
        }

    public object ПолучитьТипИзСборки(string type, string путь)
            {
                var result = НайтиТип(type);
                if (result != null)
                    return new AutoWrap(result);
                string ошибка;
                string path;
                System.Reflection.Assembly assembly;
                if (File.Exists(путь))
                    assembly = System.Reflection.Assembly.LoadFrom(путь);
                else
                { 
                    path = Path.Combine(Path.GetDirectoryName(typeof(string).Assembly.Location), путь);
                if (File.Exists(path))
                {
                    var ИмяСборки = AssemblyName.GetAssemblyName(path).FullName;
                    assembly = System.Reflection.Assembly.Load(ИмяСборки);
                }
                else
                {
                    ошибка = " Не найден файл " + путь + " или  " + path;
                    MessageBox.Show(ошибка);
                    throw new COMException(ошибка);
                }
                }
                result = assembly.GetType(type);
                if (result != null)
                {
                    return new AutoWrap(result);
                }
                 ошибка = " неверный тип " + type + " в сборке " + assembly.Location;
                MessageBox.Show(ошибка);
                throw new COMException(ошибка);
                //    return null;
            }
READ ALSO
DataGridView аля &#171;Система компоновки данных - 1С:Предприятие&#187;

DataGridView аля «Система компоновки данных - 1С:Предприятие»

Задача: есть DataGridView, в который выводится разная нужная информацияCо временем информации, которую хотят видеть, много прирастает

189
Проблема в VS, неправильное деление [дубликат]

Проблема в VS, неправильное деление [дубликат]

На данный вопрос уже ответили:

206
Унаследованный контрол добавить на ToolBox

Унаследованный контрол добавить на ToolBox

1) Я создал отдельный класс и унаследовал в нем LabelМожно ли его теперь как-то добавить на ToolBox? После компиляции он не появляется

246