给定一个具有隐式转换运算符的类:
public class MyDateTime
{
public static implicit operator MyDateTime(System.Int64 encoded)
{
return new MyDateTime(encoded);
}
public MyDateTime(System.Int64 encoded)
{
_encoded = encoded;
}
System.Int64 _encoded;
}
我现在可以做以下事情:
long a = 5;
MyDateTime b = a;
但不包括以下内容:
long f = 5;
object g = f;
MyDateTime h = g;
这会在编译时产生错误:
无法将类型“object”隐式转换为“MyDateTime”。
对我来说很有意义。
现在,我按照以下方式修改了之前的示例:
long f = 5;
object g = f;
MyDateTime h = (MyDateTime)g;
这段代码可以成功编译。但是在运行时,我得到了一个“InvalidCastException
”:
无法将类型为“System.Int64”的对象强制转换为“MyDateTime”类型。
这告诉我C#的隐式转换操作符仅在编译时生效,在.NET运行时尝试动态转换对象类型时不会被应用。
我的问题:
- 我的理解正确吗?
- 是否有其他方法可以实现此功能?
顺便说一下,我的完整应用程序中我正在使用Delegate.DynamicInvoke()
来调用需要一个MyDateTime
参数的函数,而我向DynamicInvoke
传递的参数类型是一个长整型。
Func<decimal, decimal> add = decimal.Add;
,但是对于int来说却没有这样的方法;你必须说Func<int, int> add = (x, y) => x + y
。如果所有内置类型都像Decimal一样设计,然后运行时或编译器可以选择将它们降级为更基本的操作以提高性能,那就太好了。但这种一致性真正源于“函数式”思维方式。 - Eric LippertMatrix<T> where T : IAddable<T, T>
等等。 这确实需要对语言和运行时进行一些相当严格的工作,因此它从未成为优先级列表中非常重要的事项。 - Eric LippertOperator.Add<T>
和Operator.Add<TArg1,TArg2>
)。这可以为您提供通用运算符函数,但不会给您带来更重要的类型安全。但是,您可能可以通过Code Contracts获得类似的保护。 - BrianExpression.Lambda(delegateType, Expression.Convert(getValExpr, resType), exprParameters)
的东西,但是processCallExpr
结果和object
不同。例如:processCall的类型为int
,resType类型为double
,我需要一些表达式来隐式转换它,而不是强制转换错误。 - mvorisek