Тип возвращаемого значения переменной метода в C#

Я хочу дать параметр методу, и я хочу, чтобы мой метод возвращал данные, просматривая параметр. Данные могут быть типа boolean, string, int или др. Как я могу вернуть тип переменной из метода? Я не хочу возвращать тип объекта, а затем приводить его к другому типу. Например:

BlaBla VariableReturnExampleMethod(int a)
{
    if (a == 1)
        return "Demo";
    else if (a == 2)
        return 2;
    else if (a == 3)
        return True;
    else
        return null;
}

Причина, по которой я этого хочу, в том, что у меня есть метод, который читает выбранный столбец строки из базы данных. Типы столбцов не одинаковы, но я должен возвращать информацию о каждом столбце.

6 ответов

Решение

Как я могу вернуть тип переменной из метода? Я не хочу возвращать тип объекта, а затем приводить его к другому типу.

Ну, это в основном то, что вы должны сделать. В качестве альтернативы, если вы используете C# 4, вы можете сделать тип возврата dynamic, что позволит преобразованию быть неявным:

dynamic VariableReturnExampleMethod(int a)
{
    // Body as per question
}

...

// Fine...
int x = VariableReturnExampleMethod(2);

// This will throw an exception at execution time
int y = VariableReturnExampleMethod(1);

По сути, вы указываете типы, чтобы компилятор знал, чего ожидать. Как это может работать, если тип известен только во время выполнения? Причина dynamic Работа версии заключается в том, что она в основном говорит компилятору отложить свою обычную работу до времени выполнения - так что вы теряете нормальную безопасность, которая позволила бы второму примеру потерпеть неудачу во время компиляции.

Использование dynamic Ключевое слово вместо BlahBlah если вы нацеливаетесь .Net 4.0 но если меньше, то object это ваша самая безопасная ставка, потому что это базовый класс для любого другого класса, который вы можете себе представить.

Похоже, это может быть хорошим случаем для дженериков. Если вы знаете, какой тип данных вы ожидаете, когда вызываете его, вы можете вызвать эту конкретную универсальную версию функции.

Подумайте об использовании чего-то вроде Dapper-dot-net (написанного Марком Гравеллом и Сэмом Саффроном в нашем собственном переполнении стека) для извлечения вещей из БД. Он обрабатывает базу данных для сопоставления объектов для вас.

Кроме того, если вы не хотите использовать инструмент, и вы извлекаете данные из базы данных, и вы знаете типы данных различных столбцов во время компиляции (как это звучит у вас), вы, вероятно, должны работать со строками. построчно, а не столбец за столбцом.

//Pseudo-code:
List<DatabaseObject> objects = new List<DatabaseObject>();
foreach(var row in DatabaseRows)
{
    var toAdd = new DatabaseObject();
    toAdd.StringTypeVariable = "Demo";
    toAdd.IntTypeVariable = 2;
    toAdd.BoolTypeVariable = true;
    object.Add(toAdd);
}

Примечание: вы могли бы использовать синтаксис инициализатора объекта и linq здесь, но это самый простой способ, которым я мог бы подумать о демонстрации этого, не используя кучу дополнительных вещей.

Также обратите внимание, что здесь я предполагаю, что вы на самом деле не хотите возвращать "Demo", 2 и true, но значения, которые используют строку. Это просто означает, что вы измените жестко закодированные значения на: row.GetStringType(stringColumnIdx) или что-то подобное.

Используйте тип возврата как object, тогда вы можете получить любой тип возврата. Вы должны обработать возвращаемый тип эфира с помощью отражения или другого метода.

Проверь это:

void Main()
{
    object aa = VariableReturnExampleMethod(3);
    Console.WriteLine(aa.ToString());
}

object VariableReturnExampleMethod(int a)
{
    if (a == 1)
        return "Demo";
    else if (a == 2)
        return 2;
    else if (a == 3)
        return true;
    else
        return null;
}

Изменить: Я в пользу строго типизированных объектов, и вы можете легко реализовать это на платформе.net.

if(returnedValue !=null)
{

string currentDataType = returnedValue.GetType().Name;
object valueObj = GetValueByValidating(currentDataType, stringValue);
}


 public object GetValueByValidating(string strCurrentDatatype, object valueObj)
        {
            if (valueObj != "")
            {
                if (strCurrentDatatype.ToLower().Contains("int"))
                {
                    valueObj = Convert.ToInt32(valueObj);
                }
                else if (strCurrentDatatype.ToLower().Contains("decimal"))
                {
                    valueObj = Convert.ToDecimal(valueObj);
                }
                else if (strCurrentDatatype.ToLower().Contains("double") || strCurrentDatatype.ToLower().Contains("real"))
                {
                    valueObj = Convert.ToDouble(valueObj);
                }
                else if (strCurrentDatatype.ToLower().Contains("string"))
                {
                    valueObj = Convert.ToString(valueObj);
                }
                else
                {
                    valueObj = valueObj.ToString();
                }
            }
            else
            {
                valueObj = null;
            }
            return valueObj;
        }

Я смотрю на ваши вопросы, и одна лучше, чем вторая, но последнее, что я должен переписать, чтобы лучше понять решение. И это решение долго пропускалось, если еще стек, и заменял его на foreach в перечислении Types, где мы можем реализовать все типы, которые нам нужны. Мне больше нравится использовать динамические, но это тоже можно использовать.

Основная функция GetValueByValidating Возвращаемое значение, если тип определен и возможно, в других случаях вернуть false. Посмотрите niranjan-kala, это ваша основная функция после переписывания.



            /// 
        /// Enum of wanted types
        /// 
        public enum Types
        {
            [ExtendetFlags("int")]
            INT,
            [ExtendetFlags("decimal")]
            DECIMAL,
            [ExtendetFlags("double")]
            DOUBLE,
            [ExtendetFlags("real")]
            REAL,
            [ExtendetFlags("string")]
            STRING,
            [ExtendetFlags("object")]
            OBJECT,
            [ExtendetFlags("null")]
            NULLABLE
        }
        /// 
        /// Cycle by types when in enum exist string reference on type (helper)
        /// 
        /// 
        /// 
        public static Types GetCurrentType(string container)
        {
            foreach (Types t in Enum.GetValues(typeof(Types)))
            {
                if (container.Contains(t.GetFlagValue()))
                {
                    return t;
                }
            }
            return Types.NULLABLE;
        }
        /// 
        /// Return object converted to type
        /// 
        /// 
        /// 
        /// 
        public static object GetValueByValidating(string strCurrentDatatype, object valueObj)
        {
            var _value = valueObj != null ? valueObj : null;
            try
            {
                Types _current = _value != null ? GetCurrentType(strCurrentDatatype.ToLower()) : Types.NULLABLE;

                switch (_current)
                {
                    case Types.INT:
                        valueObj = Convert.ToInt32(valueObj);
                        break;
                    case Types.DECIMAL:
                        valueObj = Convert.ToDecimal(valueObj);
                        break;
                    case Types.DOUBLE:
                        valueObj = Convert.ToDouble(valueObj);
                        break;
                    case Types.REAL:
                        valueObj = Convert.ToDouble(valueObj);
                        break;
                    case Types.STRING:
                        valueObj = Convert.ToString(valueObj);
                        break;
                    case Types.OBJECT:
                        break;
                    case Types.NULLABLE:
                        throw new InvalidCastException("Type not handled before selecting, function crashed by retype var.");
                }
            } catch (InvalidCastException ex)
            {
                Log.WriteException(ex);
                valueObj = false;
            }

            return valueObj;
        }


Другие вопросы по тегам