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

时间:2012-05-08 13:40:56

标签: c# multiple-variable-return

我想给方法一个参数,我希望我的方法通过查看参数来返回数据。数据可以是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 个答案:

答案 0 :(得分:16)

  

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

那基本上就是你必须要做的事情。或者,如果您使用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版本工作的原因是它基本上告诉编译器将其正常工作推迟到执行时间 - 因此您将失去正常的安全性,这将使第二个示例在编译时失败。

答案 1 :(得分:4)

如果您定位dynamic,请使用BlahBlah关键字代替.Net 4.0,但如果您选择较小的object,那么{{1}}是最安全的选择,因为它是其他所有人的基类你能想到的课程。

答案 2 :(得分:2)

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

答案 3 :(得分:2)

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

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

//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)或类似的东西。

答案 4 :(得分:0)

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

检查一下:

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

答案 5 :(得分:0)

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

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