为什么不会出现超载的情况呢?
我有以下课程:
class CrmToRealTypeConverter : IConverter
{
#region IConverter Members
public object Convert<T>(T obj)
{
return Convert(obj);
}
#endregion
private DateTime? Convert(CrmDateTime obj)
{
return obj.IsNull == false ? (DateTime?)obj.UserTime : null;
}
private int? Convert(CrmNumber obj)
{
return obj.IsNull == false ? (int?)obj.Value : null;
}
private decimal? Convert(CrmDecimal obj)
{
return obj.IsNull == false ? (decimal?)obj.Value : null;
}
private double? Convert(CrmDouble obj)
{
return obj.IsNull == false ? (double?)obj.Value : null;
}
private float? Convert(CrmFloat obj)
{
return obj.IsNull == false ? (float?)obj.Value : null;
}
private decimal? Convert(CrmMoney obj)
{
return obj.IsNull == false ? (decimal?)obj.Value : null;
}
private bool? Convert(CrmBoolean obj)
{
return obj.IsNull == false ? (bool?)obj.Value : null;
}
}
我正在尝试使用 concreate 类型专门化 Convert 方法。
目前它只是在 Convert
中递归循环,直到发生堆栈溢出。
I have the following class:
class CrmToRealTypeConverter : IConverter
{
#region IConverter Members
public object Convert<T>(T obj)
{
return Convert(obj);
}
#endregion
private DateTime? Convert(CrmDateTime obj)
{
return obj.IsNull == false ? (DateTime?)obj.UserTime : null;
}
private int? Convert(CrmNumber obj)
{
return obj.IsNull == false ? (int?)obj.Value : null;
}
private decimal? Convert(CrmDecimal obj)
{
return obj.IsNull == false ? (decimal?)obj.Value : null;
}
private double? Convert(CrmDouble obj)
{
return obj.IsNull == false ? (double?)obj.Value : null;
}
private float? Convert(CrmFloat obj)
{
return obj.IsNull == false ? (float?)obj.Value : null;
}
private decimal? Convert(CrmMoney obj)
{
return obj.IsNull == false ? (decimal?)obj.Value : null;
}
private bool? Convert(CrmBoolean obj)
{
return obj.IsNull == false ? (bool?)obj.Value : null;
}
}
I am trying to specialize the Convert method with concreate types.
Currently it just loops recursively in Convert<T>()
until a stack overflow occurs.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
多态性不适用于方法调用的参数。您可以使用它来检查 obj 的类型,将其转换为特定类型,然后调用适当的重载。
Polymorphism doesn't work on arguments to a method call. An approach you can use it to check the type of obj, cast it to the specific type and then call the appropriate overload.
后期绑定并不像您想象的那样发生;编译器将对
公共对象 Convert(T obj)
方法中的Convert(obj)
的调用绑定到相同方法(递归称呼)。您似乎期望的行为是 CLR 将动态选择最合适的重载来在运行时执行,但事实并非如此。请尝试这样的操作:如果您愿意,可以在此处使用反射。这样的解决方案看起来像:
Late-binding doesn't happen the way you think it does; the compiler binds the call to
Convert(obj)
in thepublic object Convert<T>(T obj)
method to the same method (recursive call). The behaviour you appear to be expecting is that the CLR will dynamically choose the most appropriate overload to execute at run-time, but it doesn't work that way. Try something like this instead:If you prefer, you can use reflection here. Such a solution would look something like:
您应该遵循的模型是 .Net Convert 类中的模型,您没有理由将构造函数设为泛型,它不会带来任何结果。将转换例程更改为静态方法,并将类本身更改为静态:
然后,当您调用其中一种转换方法时,编译器将选择要调用的正确重载:
编辑:
如果执行以下操作:
它将不起作用,因为编译器不知道与重载匹配的类型。你必须投射它并且它会起作用:
The model you should follow is the model in the .Net Convert class, there is no reason for you to make the constructor a generic, it brings nothing to the table. Change the convert routines to static methods and the class itself to static:
Then when you call one of the convert methods the compiler will select the proper overload to call:
Edit:
If you do the following:
it will not work as the compiler doesn't know the type to match the overload. You would have to cast it and it will work:
发生这种情况是因为编译器直到运行时才知道
T
的泛型类型,并在编译时将调用绑定到T = System.Object
,并且唯一合适的函数获取 System.Object 就是该函数本身。但是,在 .NET 4 中,您可以使用dynamic
关键字使运行时在运行时根据 T 动态选择正确的重载,这正是您希望发生的情况。简单的例子:
请注意,我手头上实际上没有编译器,这可能无法按字面意思进行编译,但足够接近。
This occurs because the compiler doesn't know the generic type of
T
until runtime and binds the call toT = System.Object
at compile-time, and the only function suitable to take a System.Object is that function itself. However, in .NET 4, you can use thedynamic
keyword to cause the runtime to select the correct overload dynamically based on T at runtime, which is what you are looking to happen.Simple example:
Note that I don't actually have my compiler on hand and this might not compile literally, but close enough.