Преобразовать переменную в тип, известный только во время выполнения?


86
foreach (var filter in filters)
{
    var filterType = typeof(Filters);
    var method = filterType.GetMethod(filter, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Static);
    if (method != null)
    {
        var parameters = method.GetParameters();
        Type paramType = parameters[0].ParameterType;
        value = (string)method.Invoke(null, new[] { value });
    }
}

Как я могу транслировать valueна paramType? valueэто string, paramTypeвероятно , просто базовый тип , как int, stringили , может быть float. Я не против, когда он генерирует исключение, если преобразование невозможно.




4
Комментарий @ MichaelFreidgeim является возможным дубликатом предыдущего.
— kmote

1
@kmote, комментарий «возможный дубликат» обычно создается автоматически, когда кто-то голосует за закрытие вопроса как дублирующего. Не уверен, почему система вставила тот же комментарий во второй раз вместо увеличения голоса за первый комментарий. Возможно, самый старый комментарий был создан вручную, так как он имеет
— Майкл

@kmote, это известная проблема meta.stackoverflow.com/questions/367526/…
— Майкл

Ответы:


89

Все типы, которые вы используете, реализуют IConvertible. Таким образом, вы можете использовать ChangeType.

 value = Convert.ChangeType(method.Invoke(null, new[] { value }), paramType);

13
круто ... в одну строку. var value = Convert.ChangeType (objectValue, objectType);
— Rigin

17

Вы могли бы двигаться динамично; например:

using System;

namespace TypeCaster
{
    class Program
    {
        internal static void Main(string[] args)
        {
            Parent p = new Parent() { name = "I am the parent", type = "TypeCaster.ChildA" };
            dynamic a = Convert.ChangeType(new ChildA(p.name), Type.GetType(p.type));
            Console.WriteLine(a.Name);

            p.type = "TypeCaster.ChildB";
            dynamic b = Convert.ChangeType(new ChildB(p.name), Type.GetType(p.type));
            Console.WriteLine(b.Name);
        }
    }

    internal class Parent
    {
        internal string type { get; set; }
        internal string name { get; set; }

        internal Parent() { }
    }

    internal class ChildA : Parent
    {
        internal ChildA(string name)
        {
            base.name = name + " in A";
        }

        public string Name
        {
            get { return base.name; }
        }
    }

    internal class ChildB : Parent
    {
        internal ChildB(string name)
        {
            base.name = name + " in B";
        }

        public string Name
        {
            get { return base.name; }
        }
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.