11

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

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

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

4

6 回答 6

18

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

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

于 2012-05-08T13:42:37.153 回答
4

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

于 2012-05-08T13:44:33.950 回答
2

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

于 2012-05-08T13:45:16.637 回答
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)或类似的东西。

于 2012-05-08T13:47:20.037 回答
0

使用返回类型 as 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;
        }
于 2012-05-08T13:45:12.290 回答
0

我看看你的问题,一个比第二个好,但最后我必须重写以更好地理解解决方案。这个解决方案跳过了很长的 if else stack 并在 Types 枚举上用 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;
        }


于 2016-03-23T08:21:30.357 回答