none
Как привести некоторое значение к типу Type t? RRS feed

  • Вопрос

  • Есть метод, который по некоторому строковому значению возвращает тип C#:

     public static Type GetCSharpType(string type)
            {
                switch (type)
                {
                    case "t1":       return typeof(System.SByte);
                    case "t2":       return typeof(System.Int16);
                    case "t3":       return typeof(System.Int32);
                    case "t4":       return typeof(System.Int64);
                }
                return typeof(System.Object);
            }

    Метод, который возвращает значение по умолчанию для этого типа:

    public static object GetDefaultValue(Type t)
            {
                if (t.IsValueType)
                {
                    return Activator.CreateInstance(t);
                }
                else
                {
                    return null;
                }
            }

    Далее мне нужно в другой метод передать полученное значение по умолчанию для этого типа, приведенное к этому типу (например, как бы это было для целого (Int32) default(Int32)):

    Type t = GetCSharpType(types[0]);
    object defv = GetDefaultValue(t);
    MyMethod (0,0,(t) defv);

    Но это не работает! Уже всю голову сломал, не могу привести значение к типу, возвращенному из GetCSHarpType()

    11 апреля 2012 г. 11:33

Ответы

  • Прошу прощения, MyMethod может быть и не статиком и вызываться из внешней библиотеки, код которой закрыт

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

    Если метод всего один, то можно в switch-case расписать его вызов с нужными типами.


    Для связи [mail]

    • Помечено в качестве ответа tzi0 12 апреля 2012 г. 6:53
    11 апреля 2012 г. 14:23

Все ответы

  • Добрый день.

    Можно так:

            static void Main()
            {
                Type t = typeof(Int32);
     
                object defv = GetDefaultValue(t);
     
                Test test = new Test();
     
                test.GetType().GetMethod("MyMethod")
                            .MakeGenericMethod(t)
                            .Invoke(test, new object[] { 0, 0, defv });
            }
      
            public class Test
            {
                public void MyMethod<T>(int a , int b, T defv)
                {
                    Console.WriteLine(typeof(T));
                    Console.WriteLine(defv);
                }
            }
    

    11 апреля 2012 г. 12:09
  • Есть нелько способов решения подобных проблем. Использовать тип dynamic, самый лёгкий и короткий. Использовать рефлексию или динамическую компиляцию (деревья выражений) - более длинные, но эффективные способы. Но пока, что не очень понятна логика работы вашего кода

    1. Зачем принимать некий условный тип возвращать системный?
    2. Метод GetDefaultValue принимает значимый тип и возвращает null в случае неудачи, могут возникнуть проблемы если принимающий метод будет ждать значимый тип. И самое главное не понятно что Вы там пытаетесь реализовать?
    3. Собственно вопрос у Вас есть строковое имя типа  и хотите привести его к этому типу или хотите передать просто его значение в другую функцию?

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

    11 апреля 2012 г. 12:42
    Модератор
  • Прошу прощения, MyMethod может быть и не статиком и вызываться из внешней библиотеки, код которой закрыт
    11 апреля 2012 г. 12:54
  • Есть нелько способов решения подобных проблем. Использовать тип dynamic, самый лёгкий и короткий. Использовать рефлексию или динамическую компиляцию (деревья выражений) - более длинные, но эффективные способы. Но пока, что не очень понятна логика работы вашего кода

    1. Зачем принимать некий условный тип возвращать системный?
    2. Метод GetDefaultValue принимает значимый тип и возвращает null в случае неудачи, могут возникнуть проблемы если принимающий метод будет ждать значимый тип. И самое главное не понятно что Вы там пытаетесь реализовать?
    3. Собственно вопрос у Вас есть строковое имя типа  и хотите привести его к этому типу или хотите передать просто его значение в другую функцию?

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

    1. Есть файл с описанием OPC тэгов, в котором одним из параметров является тип тэга ("VT_I4", н-р, что соответствует типу Int32).

    2. Принимающий метод работает и с null значениями

    3. Мне нужно передать значение по умолчанию для данного типа, при этом привести его к этому типу.

    Зачем: есть метод, который создает тэг в OPC сервере. Этот метод обязательно принимает параметр "значение по умолчанию для тэга". Как я могу определить значение по умолчанию? Никак.

    11 апреля 2012 г. 13:12
  • Используйте return default(T) вместо return null и GetDefaultValue() сделайте дженериком.
    • Предложено в качестве ответа ulcerModerator 12 апреля 2012 г. 10:22
    11 апреля 2012 г. 14:23
    Отвечающий
  • Прошу прощения, MyMethod может быть и не статиком и вызываться из внешней библиотеки, код которой закрыт

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

    Если метод всего один, то можно в switch-case расписать его вызов с нужными типами.


    Для связи [mail]

    • Помечено в качестве ответа tzi0 12 апреля 2012 г. 6:53
    11 апреля 2012 г. 14:23
  • Используйте return default(T) вместо return null и GetDefaultValue() сделайте дженериком.
    Как в таокм случае передать тип как параметр, возвращенный из GetCSharpType?
    12 апреля 2012 г. 6:41
  • Сделал через switch-case. Другими способами не получилось...
    12 апреля 2012 г. 6:53
  • А зачем его передавать как параметр? Используйте без параметров :)
    12 апреля 2012 г. 13:14
    Отвечающий