C#中方法的变量返回类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10499791/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 14:05:37  来源:igfitidea点击:

Variable Return Type of a Method in C#

c#multiple-variable-return

提问by sanchop22

I want to give a parameter to a method and i want my method to return data by looking the parameter. Data can be in type of boolean, string, int or etc. How can i return a variable type from a method? I don't want to return an object type and then cast it to another type. For example:

我想给一个方法一个参数,我希望我的方法通过查看参数来返回数据。数据可以是布尔值、字符串、整数等类型。如何从方法返回变量类型?我不想返回一个对象类型,然后将其转换为另一种类型。例如:

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

The reason why i want that is i have a method that reads a selected column of a row from the database. Types of columns are not same but i have to return every column's information.

我想要的原因是我有一种方法可以从数据库中读取行的选定列。列的类型不同,但我必须返回每一列的信息。

采纳答案by Jon Skeet

How can i return a variable type from a method? I don't want to return an object type and then cast it to another type.

如何从方法返回变量类型?我不想返回一个对象类型,然后将其转换为另一种类型。

Well that's basically what you dohave to do. Alternatively, if you're using C# 4 you could make the return type dynamic, which will allow the conversion to be implicit:

嗯,这基本上你什么必须做的。或者,如果您使用的是 C# 4,您可以设置 return type 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);

Fundamentally, you specify types to let the compilerknow what to expect. How can that work if the type is only known at executiontime? The reason the dynamicversion works is that it basically tells the compiler to defer its normal work untilexecution time - so you lose the normal safety which would let the second example fail at compile time.

从根本上说,您指定类型是为了让编译器知道会发生什么。如果类型仅在执行时已知,那如何工作?该dynamic版本有效的原因是它基本上告诉编译器将其正常工作推迟执行时间 - 因此您失去了正常安全性,这将使第二个示例在编译时失败。

回答by Nikhil Agrawal

Use dynamicKeyword in place of BlahBlahif you are targeting .Net 4.0but if lesser one then objectis your safest bet because it is the base class for every other class you can think of.

如果您的目标是dynamic关键字,BlahBlah则使用关键字代替,.Net 4.0但如果较小,则object是您最安全的选择,因为它是您能想到的所有其他类的基类。

回答by Niranjan Singh

Use return type as object, then you are able to get any return type. you have to handle the return type ether through reflection or other method.

使用 return type as object,然后您就可以获得任何返回类型。您必须通过反射或其他方法处理返回类型 ether。

check this:

检查这个:

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

Edit: I am in the favor of strongly typed objects and you can implement it easily on .net platform.

编辑:我赞成强类型对象,您可以在 .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;
        }

回答by Tim

It sounds like this might be a good case for generics. If you know what data type you're expecting when you call it, you can call that particular generic version of the function.

听起来这可能是泛型的好例子。如果您知道调用它时所期望的数据类型,则可以调用该函数的特定通用版本。

回答by Chris Pfohl

Consider using something like Dapper-dot-net (written by Marc Gravell and Sam Saffron at our very own Stack Overflow) to pull things out of the DB. It handles the database to object mapping for you.

考虑使用类似 Dapper-dot-net(由 Marc Gravell 和 Sam Saffron 在我们自己的 Stack Overflow 上编写)之类的东西从数据库中提取东西。它为您处理数据库到对象的映射。

Furthermore, if you don't want to use a tool, and you're pulling from a Database, and you know the data types of the various columns at compile time (like it sounds you do), you should probably be working row-by-row rather than column-by-column.

此外,如果您不想使用工具,并且您正在从数据库中提取,并且您在编译时知道各个列的数据类型(就像您听起来那样),那么您可能应该在行工作 -逐行而不是逐列。

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

Note: you could use object initializer syntax, and linq here but this is the most basic way I could think of demoing this without using a ton of extra stuff.

注意:您可以在这里使用对象初始值设定项语法和 linq,但这是我能想到的在不使用大量额外内容的情况下进行演示的最基本方式。

Also note, that here I'm assuming that you don't actuallywant to return "Demo", 2, and true, but values that use the row. That just means you'd change the hard coded values to: row.GetStringType(stringColumnIdx)or something similar.

另请注意,这里我假设您实际上不想返回“Demo”、2 和 true,而是使用该行的值。这只是意味着您将硬编码值更改为:row.GetStringType(stringColumnIdx)或类似的值。

回答by Michael Gordon

I look on your asks and one is better than second, but last i must rewritting to better understand solution. And this solution skiped long if else stack and replacing it by foreach on Types enum, where we can implement all types what we need. I more like using dynamic, but this is usable too.

我看着你的问题,一个比第二个好,但最后我必须重写以更好地理解解决方案。这个解决方案跳过了很长的 if else 堆栈,并在 Types 枚举上用 foreach 替换它,在那里我们可以实现我们需要的所有类型。我更喜欢使用动态,但这也可用。

Main function GetValueByValidatingreturned value if is type defined and possible, in other cases return false Look niranjan-kalathis is your main function after rewriting.

主函数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;
        }