我有一个C#wraper类,其中包含一系列接受各种数据类型的方法:
public class MyClass
{
public void ProcessString(string Value) { // implementation }
public void ProcessInt(int? Value) { // implementation }\
public void ProcessOther(MyClass Value) { // implementation }
}
我现在想要添加一个通用的ProcessObject()
方法,以避免在调用相关的流程方法之前显式转换对象:
public void ProcessObject(object Value)
{
if (CanCastToString(Value)
{
ProcessString((string)Value);
}
else if (CanCastToInt(Value))
{
ProcessInt((int?)Value);
}
// etc...
}
麻烦的是我不知道我的CanCastToInt
方法应该是什么 - 我需要这些方法能够健壮并处理可空类型和其他用户定义的转换。
我该怎么做?我想知道的是,是否可以将给定对象强制转换为给定类型,即是否:
(SomeType)Value
会工作。
答案 0 :(得分:4)
通常有两种主要方式:
if (Value is SomeType)
{
// Do something with a cast
}
或
var v = Value as SomeType;
if (v != null)
{
// Value was successfully cast as SomeType
}
使用结构体或内部类型时,请将它们设为可为空:
var v = Value as int?;
if (v != null)
{
ProcessInt(v.Value);
}
答案 1 :(得分:1)
您需要is
运营商。 CanCastToString(x)
- > x is string
。
答案 2 :(得分:1)
为什么不直接公开您的处理API,并为各种参数提供重载?
public class MyClass
{
public void Process(string Value) { // implementation }
public void Process(int Value) { // implementation }\
public void Process(MyClass Value) { // implementation }
public void Process(object Value) { // catch all method. Handle unknown entities, e.g. call ToString() }
}
编辑使用一些泛型魔法,您可以使用单个接口方法,一组辅助方法来完成工作,还有一个全能方法来处理极端情况。
public class MyClass
{
void DoProcess(string Value) { // implementation }
void DoProcess(int Value) { // implementation }\
void DoProcess(MyClass Value) { // implementation }
void DoProcess(object Value) {
// catch all method. Handle unknown entities, e.g. call ToString()
}
public void Process<T>(T value) {
//this method will call the right overload of DoProcess depending on the compile time type of value. If there isn't a match, it goes to DoProcess(object)
DoProcess(value);
}
}
这样可以避免对基本类型进行装箱,并且类型安全性稍好一些。
对于全能方法,您可以尝试使用Type.IsAssignableFrom
方法。例如:
if (typeof(short).IsAssignableFrom(Value)
DoProcess((short)Value);
if (typeof(byte).IsAssignableFrom(Value)
DoProcess((byte)Value);
我建议您阅读Eric Lippert关于代表性演员的文章。希望在执行此操作之后,您将意识到每个受支持的类型都可能更容易过载。此外,您可能会意识到处理拆箱值类型可能是通往地狱的道路。
答案 3 :(得分:1)
如果(与OP不同?)您不知道运行时所涉及的类型,您可能会尝试使用其中的一些变体:
http://codegoeshere.blogspot.com/2007/05/dynamic-cast-in-c.html
答案 4 :(得分:-1)
public void QuickTest()
{
object stringObj = "string";
object nullableInt1 = (int?)null;
object nullableInt2 = (int?)1;
object decimalObj = 1.5m;
ProcessObject(stringObj);
ProcessObject(nullableInt1);
ProcessObject(nullableInt2);
ProcessObject(decimalObj);
}
public void ProcessObject(object value)
{
if (value == null)
{
Debug.WriteLine("null");
return;
}
if (value is string)
{
Debug.WriteLine((string)value);
return;
}
string stringValue = value.ToString();
int intTemp;
if (int.TryParse(stringValue, out intTemp))
{
Debug.WriteLine(intTemp);
return;
}
decimal decimalTemp;
if (decimal.TryParse(stringValue, out decimalTemp))
{
Debug.WriteLine(decimalTemp);
return;
}
// etc...
}