在运行时确定(C#)
我有一系列的受理各种数据类型的方法C#wraper类:在运行时确定(C#)
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
方法应该是什么 - 我需要这些方法可以是稳健和处理像可为空的类型和其他用户定义的ca STS。
我该怎么做?所有我想知道的是,如果给定的对象可以转换为给定类型,即无论是否:
(SomeType)Value
会工作。
主要有两种方式这通常是:
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);
}
您需要is
运营商。 CanCastToString(x)
- >x is string
。
不起作用 - 考虑'x'为'Nullable
@Kragen:你确定吗?假设表达式是编译时类型为空的
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...
}
为什么不暴露你的proc直接使用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() }
}
编辑随着一些仿制药的魔法,你可以有一个单一的接口方法,一堆的helper方法做,你处理极端情况的工作和一个包罗万象的方法。
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关于演绎演员的散文。希望在做完这些之后,你会意识到对每种支持的类型重载可能会更容易。另外,你可能会意识到,处理拆箱价值类型可能是通向地狱的道路。
我已经有了,但是我也希望公开一个使用对象的泛型方法,因为它使得其他地方更容易。 – Justin 2010-06-23 06:33:53
如果(与OP?)你不知道涉及到运行时类型,你可以尝试采用这样一些变化:关于*表示改变铸件
http://codegoeshere.blogspot.com/2007/05/dynamic-cast-in-c.html
你关心*?也就是说,假设你的对象有一个盒装的短小的东西。你想能够将它转换为int吗?你不能直接将盒装短片投射到int;你必须首先将它转换为int,然后再缩写。您可能想阅读我关于这个主题的文章,以确保您了解这里发生了什么:http://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx – 2010-06-23 02:03:22
他们必须是盒装价值类型吗?通常情况下,执行此操作的OO方法是使用Process方法创建接口,每个类型都继承您,然后只调用对象上的方法,而不用担心它是什么类型。 – 2010-06-23 08:50:00