Переменный тип возврата метода в C#

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

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 ответов


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

Ну, это в основном то, что вы do нужно сделать. Кроме того, если вы используете 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 на типы enum, где мы можем реализовать все типы, что нам нужно. Мне больше нравится использовать dynamic, но это тоже можно использовать.

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



            /// 
        /// 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;
        }