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

本文关键字:变量 返回类型 方法 | 更新日期: 2023-09-27 18:33:41

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

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

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

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

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

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

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

听起来这可能是

泛型的一个很好的例子。如果在调用函数时知道所需的数据类型,则可以调用函数的特定泛型版本。

考虑使用像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)或类似内容。

使用返回类型作为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替换它,我们可以在其中实现我们需要的所有类型。我更喜欢使用动态,但这也是可用的。

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