Преобразование в Enum с использованием переменной типа - PullRequest
3 голосов
/ 05 октября 2011

Часть моего программного обеспечения использует отражение.У меня проблема в том, что, хотя я могу получить тип свойства, я не могу преобразовать строковое значение, используя Type из PropertyInfo.Вот почему я использую t в примере кода.

Приведенный ниже код демонстрирует проблему с сообщением об ошибке в виде комментария кода.Синтаксическая ошибка на t.как я могу решить эту проблему?спасибо

class Program
{
    static void Main(string[] args)
    {
        Type t = typeof(Letters);

        Letters letter = "A".ToEnum<t>(); //-- Type or namespace expected.
    }
}

public enum Letters { A, B, C }

//-- This is a copy of the EmunHelper functions from our tools library.
public static class EnumExt
{
    public static T ToEnum<T>(this string @string)
    {
        int tryInt;
        if (Int32.TryParse(@string, out tryInt)) return tryInt.ToEnum<T>();
        return (T)Enum.Parse(typeof(T), @string);
    }
    public static T ToEnum<T>(this int @int)
    {
        return (T)Enum.ToObject(typeof(T), @int);
    }
}

Решение:

Следующее работает, потому что, когда значение устанавливается с помощью отражения, принимается фактический тип Enum.Где myObject.Letter = result нет.

Type t = currentProperty.PropertyType;
Enum result = Enum.Parse(t, @string) as Enum;
ReflectionHelper.SetProperty(entity, "LetterPropertyName", result);

Спасибо всем за помощь.

Ответы [ 4 ]

4 голосов
/ 06 октября 2011
Enum.Parse(t, @string) as Enum;

Это соответствует тому же решению, которое вы разместили.

4 голосов
/ 05 октября 2011

Чтобы иметь возможность вызывать универсальный метод, тип должен быть известен во время компиляции. Вы используете неверный синтаксис.

Чтобы иметь возможность вызывать ваш метод, вы должны будете использовать отражение, чтобы получить ссылку на правильную обобщенную функцию, чтобы вы могли вызывать ее.

public static object ToEnum(this string s, Type type)
{
    var eeType = typeof(EnumExt);
    var method = eeType.GetMethod("ToEnum", new[] { typeof(string) })
                       .MakeGenericMethod(type);
    return method.Invoke(null, new[] { s });
}

Тогда вы могли бы назвать это:

Letters letter = (Letters)"A".ToEnum(t);

p.s., Я настоятельно призываю вас изменить имена переменных на что-то другое. То, что вы можете называть свои переменные в качестве ключевых слов, не означает, что вы должны.

2 голосов
/ 05 октября 2011

Я не эксперт по рефлексии, но это работает:

static void Main(string[] args)
{
    Type t = typeof(Letters);

    MethodInfo info = typeof(EnumExt).GetMethod("ToEnum", new Type[] { typeof(string) });
    var method = info.MakeGenericMethod(new Type[] { t });
    var result = (Letters)method.Invoke(null, new [] { "A" });            

    Console.ReadLine();
}
1 голос
/ 05 октября 2011

Я думаю, что ваш вопрос можно понять двумя способами: я) вы хотите исправить синтаксическую ошибку II) вам нужна рабочая реализация для функции, которую вы предоставляете

Для i) я бы предложил вам изменить:

Letters letter = "A".ToEnum<t>()

в

Letters letter = "A".ToEnum<Letters>()

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

Для ii) вы можете изменить способ предоставления аргумента типа с «универсального» аргумента на «обычный» аргумент (как предложил Джефф Меркадо). Таким образом, прототип вашей функции становится:

public static T ToEnum(this string @string, Type t)

Я заключаю с двумя замечаниями:

  • рефлексия ОЧЕНЬ медленная для моего опыта. Однажды я написал синтаксический анализатор ассемблеров, широко использующий рефлексию перечислений для имен регистров. Раньше он работал в течение нескольких минут (из-за чего отладчик VS жаловался на отсутствие ответа), когда эквивалентная версия без каких-либо отражений выполнялась менее чем за 10 секунд.

  • , как отметил Джефф Меркадо, я не вижу веских оснований для того, чтобы вы использовали одинаковые слова для имен типов и переменных

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...