public void Type_Convert() { MyValue my = new MyValue("a"); string myStr = my; Assert.AreEqual("a", myStr); my = myStr; Assert.AreEqual("a", my.Value); MyValue2 my2 = new MyValue2("a2"); myStr = my2; //my2 = myStr;//can't convert Assert.AreEqual("a2", myStr); MyValue3 my3 = myStr; myStr = my3; Func <object, Type, object> convert = (value, toType) => { Type fromType = value.GetType(); InvocationDelegate eval; var compile = new CompileContext(); compile.OverrideOperator(typeof(MyValue)); compile.AddVariable(fromType, "a"); using (compile.BeginScope()) { var expr = Convert(Variable(fromType, "a"), toType); eval = compile.Compile(expr); } ExpressionContext ctx = new ExpressionContext(); ctx.AddVariable(fromType, "a"); ctx.SetVariable("a", value); return(eval(ctx)); }; object result; result = convert(new MyValue("Hello World"), typeof(string)); Assert.AreEqual("Hello World", result); result = convert("Hello World", typeof(MyValue)); Assert.AreEqual("Hello World", ((MyValue)result).Value); result = convert(new MyValue2("Hello World"), typeof(string)); Assert.AreEqual("Hello World", result); try { result = convert("Hello World", typeof(MyValue2)); Assert.AreEqual("Hello World", ((MyValue2)result).Value); Assert.Fail(); } catch (OperatorNotImplementedException ex) { } result = convert(new MyValue3("Hello World"), typeof(string)); Assert.AreEqual("Hello World", result); result = convert("Hello World", typeof(MyValue3)); Assert.AreEqual("Hello World", ((MyValue3)result).Value); }