在运行时确定是否允许强制转换(C#)
我有一个C#wrapper类,它有一系列接受各种数据类型的方法:在运行时确定是否允许强制转换(C#),c#,reflection,casting,C#,Reflection,Casting,我有一个C#wrapper类,它有一系列接受各种数据类型的方法: public class MyClass { public void ProcessString(string Value) { // implementation } public void ProcessInt(int? Value) { // implementation }\ public void ProcessOther(MyClass Value) { // implementation }
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
将工作。您需要的
是操作员CanCastToString(x)
->x是字符串
您需要is
运算符CanCastToString(x)
->x是字符串
通常有两种主要方法:
if (Value is SomeType)
{
// Do something with a cast
}
或
使用结构或内部类型时,使其可为空:
var v = Value as int?;
if (v != null)
{
ProcessInt(v.Value);
}
这通常有两种主要方式:
if (Value is SomeType)
{
// Do something with a cast
}
或
使用结构或内部类型时,使其可为空:
var v = Value as int?;
if (v != null)
{
ProcessInt(v.Value);
}
为什么不直接公开处理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);
}
}
我建议你读一读埃里克·利珀特(Eric Lippert)关于表现型演员的文章。希望在这样做之后,您会意识到为每个受支持的类型设置重载可能会更容易。此外,您可能会意识到,处理解装箱值类型可能是一条地狱之路。为什么不直接公开处理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);
}
}
我建议你读一读埃里克·利珀特(Eric Lippert)关于表现型演员的文章。希望在这样做之后,您会意识到为每个受支持的类型设置重载可能会更容易。此外,您可能会意识到,处理解装箱值类型可能是一条通往地狱的路。如果(与OP不同)您在运行时之前不知道所涉及的类型,您可以尝试采用以下一些变体:
如果(与OP不同),您在运行时之前不知道所涉及的类型,您可以尝试采用以下一些变体:
不起作用。考虑<代码> x>代码>是<代码>可空< /COD>,然后<代码> x是int < /C> >返回false,但是<代码>(int)x>代码>运行良好。@ Kragen:您确定吗?假设表达式的编译时类型为Nullable。然后您不需要“is”操作符,因为您已经知道对象的确切类型。假设表达式不是可为null的编译时类型。可能是什么类型的?一定是盒装的东西。没有装箱的可为null的int!一个可空的int,要么是空引用,要么是装箱的int(对你来说是个谜:我的分析不完全正确。我错过了什么情况?)不起作用。考虑代码< > x>代码>是一个<代码>可忽略的< /代码>,然后<代码> x是int 返回false,但是<代码>(int)x>代码>工作得很好。@ Kragen:你确定吗?假设表达式的编译时类型为Nullable。然后您不需要“is”操作符,因为您已经知道对象的确切类型。假设表达式不是可为null的编译时类型。可能是什么类型的?一定是盒装的东西。没有装箱的可为null的int!一个可为null的int可以是一个null引用框,也可以是一个已装箱的int。(对你来说是一个难题:我的分析不完全正确。我遗漏了什么情况?)你关心表示形式的转换吗?也就是说,假设您的对象中有一个短框。你想把它转换成int吗?您不能直接将盒装短码转换为int;您必须先将其转换为int,然后再转换为short。你可能想阅读我关于这个主题的文章,以确保你理解这里发生的事情:它们必须是装箱的值类型吗?通常,OO实现这一点的方法是使用每个类型继承的流程方法创建一个接口,然后只调用对象上的方法,而不必担心它是什么类型。您关心表示形式的更改吗?也就是说,假设您的对象中有一个短框。你想把它转换成int吗?您不能直接将盒装短码转换为int;您必须先将其转换为int,然后再转换为short。你可能想阅读我关于这个主题的文章,以确保你理解这里发生的事情:它们必须是装箱的值类型吗?通常情况下,OO的方法是创建一个接口,其中包含一个流程方法,每个类型都继承该方法,然后对对象调用该方法,而不必担心它是什么类型。我已经说过了,但我还想公开一个使用对象的泛型方法,因为它使其他地方的事情变得更简单。我已经说过,但我还想公开一个使用对象的通用方法,因为它使其他地方的事情变得更容易。