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