首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >隐式转换动态到DateTime?和op_Equality

隐式转换动态到DateTime?和op_Equality
EN

Stack Overflow用户
提问于 2015-01-14 13:11:36
回答 1查看 936关注 0票数 3

我有自己的动态对象,它必须与原始类型相比较。我为所有要比较的类型定义了隐式强制转换运算符。对于大多数原语类型(如int、short、bool、十进制实现),这种类型的强制转换为空版本对于成功地进行比较是足够的,但对于DateTime则不够。我是否错过了DateTime和十进制之间的显著差异,还是在动态实现中出现了错误?

代码语言:javascript
复制
class MyDynamic : DynamicObject
{
    public static implicit operator decimal?(MyDynamic nullable)
    {
        return null;
    }

    public static implicit operator DateTime?(MyDynamic x)
    {
        return null;
    }

    //public static implicit operator DateTime(MyDynamic x)
    //{
    //    return DateTime.MinValue;
    //}
}

[Fact]
public void FactMethodName()
{
    dynamic my = new MyDynamic();

    dynamic date = DateTime.Now;
    dynamic dec = 1m;

    Assert.False(dec == my);
    // throws
    Assert.False(date == my);
}

如果未定义隐式强制转换,则错误消息为:

代码语言:javascript
复制
System.InvalidOperationExceptionThe operands for operator 'Equal' do not match the parameters of method 'op_Equality'.

堆栈跟踪是:

代码语言:javascript
复制
System.InvalidOperationExceptionThe operands for operator 'Equal' do not match the parameters of method 'op_Equality'.
   at System.Linq.Expressions.Expression.GetMethodBasedBinaryOperator(ExpressionType binaryType, Expression left, Expression right, MethodInfo method, Boolean liftToNull)
   at System.Linq.Expressions.Expression.Equal(Expression left, Expression right, Boolean liftToNull, MethodInfo method)
   at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.GenerateUserDefinedBinaryOperator(EXPRCALL pExpr)
   at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.VisitCALL(EXPRCALL pExpr)
   at Microsoft.CSharp.RuntimeBinder.Semantics.ExprVisitorBase.Dispatch(EXPR pExpr)
   at Microsoft.CSharp.RuntimeBinder.Semantics.ExprVisitorBase.Visit(EXPR pExpr)
   at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.GenerateLambda(EXPRCALL pExpr)
   at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.VisitCALL(EXPRCALL pExpr)
   at Microsoft.CSharp.RuntimeBinder.Semantics.ExprVisitorBase.Dispatch(EXPR pExpr)
   at Microsoft.CSharp.RuntimeBinder.Semantics.ExprVisitorBase.Visit(EXPR pExpr)
   at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.Rewrite(TypeManager typeManager, EXPR pExpr, IEnumerable`1 listOfParameters)
   at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.CreateExpressionTreeFromResult(IEnumerable`1 parameters, ArgumentObject[] arguments, Scope pScope, EXPR pResult)
   at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.BindCore(DynamicMetaObjectBinder payload, IEnumerable`1 parameters, DynamicMetaObject[] args, ref DynamicMetaObject deferredBinding)
   at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.Bind(DynamicMetaObjectBinder payload, IEnumerable`1 parameters, DynamicMetaObject[] args, ref DynamicMetaObject deferredBinding)
   at Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(DynamicMetaObjectBinder action, RuntimeBinder binder, IEnumerable`1 args, IEnumerable`1 arginfos, DynamicMetaObject onBindingError)
   at Microsoft.CSharp.RuntimeBinder.CSharpBinaryOperationBinder.FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg, DynamicMetaObject errorSuggestion)
   at System.Dynamic.BinaryOperationBinder.FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg)
   at System.Dynamic.DynamicMetaObject.BindBinaryOperation(BinaryOperationBinder binder, DynamicMetaObject arg)
   at System.Dynamic.BinaryOperationBinder.Bind(DynamicMetaObject target, DynamicMetaObject[] args)
   at System.Dynamic.DynamicMetaObjectBinder.Bind(Object[] args, ReadOnlyCollection`1 parameters, LabelTarget returnLabel)
   at System.Runtime.CompilerServices.CallSiteBinder.BindCore(CallSite`1 site, Object[] args)
   at System.Dynamic.UpdateDelegates.UpdateAndExecute2<T0,T1,TRet>(CallSite site, T0 arg0, T1 arg1)

在大多数情况下,我的自定义动态应该几乎是空的,所以转换到值类型是不需要的。

EN

回答 1

Stack Overflow用户

发布于 2015-01-25 15:29:29

定义操作符==使代码更简单。

代码语言:javascript
复制
public static bool operator ==(MyDynamic lhs, object rhs)
{
    if (rhs is MyDynamic)
        return lhs.Equals(rhs);
    else
        return false;
}
public static bool operator !=(MyDynamic lhs, object rhs)
{
    if (rhs is MyDynamic)
        return !lhs.Equals(rhs);
    else
        return true;
}

public static bool operator ==(object lhs, MyDynamic rhs)
{
    if (lhs is MyDynamic)
        return lhs.Equals(rhs);
    else
        return false;
}
public static bool operator !=(object lhs, MyDynamic rhs)
{
    if (lhs is MyDynamic)
        return !lhs.Equals(rhs);
    else
        return true;
}

编辑i显式实现(MyDynamic ==对象)和(object == MyDynamic)。因为覆盖TryBinaryOperation()无法捕获(对象== MyDynamic)的情况。

代码语言:javascript
复制
public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result) 
{
    if (binder.Operation == System.Linq.Expressions.ExpressionType.Equal) { ... }

    return base.TryBinaryOperation(binder, arg, out result);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27943780

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档