Vek*_*ksi 0 .net c# reflection
我是用汇编代表摆弄,并试图调用Serialize和Deserialize函数使用编译代表(不介意的名字)下面的类.我成功地打电话Serialize,但没有Deserialize.问题似乎是我似乎不明白如何将string参数传递给Func下面代码中的对象.有谁知道我的代码(和大脑)的修复?
public class SomeClass
{
public string SomeString { get; }
public SomeClass(string str)
{
SomeString = str;
}
public string Serialize()
{
return SomeString;
}
public SomeClass Deserialize(string str)
{
return new SomeClass(str + " - !!!!");
}
}
public class Program
{
private static class TypeSerializationCache<T>
{
public static readonly Func<T, string> Serialize;
public static readonly Func<string, T> DeserializeThatShouldBe;
public static readonly Func<T, string, T> DeserializeOriginalFixed;
static TypeSerializationCache()
{
const string SerializeFunctionToCall = "Serialize";
var serializeFuncParameterValue = Expression.Parameter(typeof(T), "serializeFuncParameterValue");
var serializeMethod = typeof(T).GetMethod(SerializeFunctionToCall, BindingFlags.Instance | BindingFlags.Public, null, new Type[] { }, null);
var serializeCall = serializeMethod != null ? (Expression)Expression.Call(serializeFuncParameterValue, serializeMethod) : Expression.Constant(default(T), typeof(T));
Serialize = Expression.Lambda<Func<T, string>>(serializeCall, serializeFuncParameterValue).Compile();
const string DeserializeCallFunction = "Deserialize";
var deserializeFuncParameterValue = Expression.Parameter(typeof(T), "DeserializeFuncParameterValue");
var deserializeMethod = typeof(T).GetMethod(DeserializeCallFunction, BindingFlags.Instance | BindingFlags.Public, null, new Type[] { typeof(string) }, null);
var deserializeArgument = Expression.Parameter(typeof(string), "deserializeArgument");
var deserializeCall = Expression.Call(deserializeFuncParameterValue, deserializeMethod, deserializeArgument);
DeserializeOriginalFixed = Expression.Lambda<Func<T, string, T>>(deserializeCall, deserializeFuncParameterValue, deserializeArgument).Compile();
//To my great dismay, the following throws.
DeserializeThatShouldBe = Expression.Lambda<Func<string, T>>(deserializeCall, deserializeFuncParameterValue, deserializeArgument).Compile();
}
}
public static void Main(string[] args)
{
var class11 = new SomeClass("XYZ");
var class12 = new SomeClass("123");
var class31 = TypeSerializationCache<SomeClass>.Serialize(class11);
var class32 = TypeSerializationCache<SomeClass>.Serialize(class12);
var class31d = TypeSerializationCache<SomeClass>.DeserializeOriginalFixed(class11, class31);
var class32d = TypeSerializationCache<SomeClass>.DeserializeThatShouldBe(class32);
}
Run Code Online (Sandbox Code Playgroud)
<编辑:我需要回来(清醒)并尝试修复参数的数量.不是我希望的,理想情况下我只想使用type参数和序列化字符串.另外,鸭子谈话让我想起了bug.:)
Aanyway,我仍然在寻找根本修复,而不仅仅是创可贴......
<编辑2:现在,根修复似乎在我的大脑中,并且理解一个实例方法或静态方法需要一个实例.我想我的鸭子排成一排,并且在闭上眼睛之后计算好了.我要感谢Eric.
有没有人知道我的代码修复
向错误所在的程序员展示,他们修复了这个bug. 教程序员如何找到错误,他们停止发布他们的错误代码供其他人调试,节省每个人的时间.
获得一只橡皮鸭.大声读出这条线给鸭子.
var deserializeFuncParameterValue = Expression.Parameter(typeof(T), "DeserializeFuncParameterValue");
Run Code Online (Sandbox Code Playgroud)
现在大声读出这条线给鸭子.
Deserialize = Expression.Lambda<Func<string, T>>(deserializeCall, deserializeFuncParameterValue, deserializeArgument).Compile();
Run Code Online (Sandbox Code Playgroud)
现在向鸭子解释鸭子完全不知道表达树为什么代码是正确的.由于代码不正确,您应该无法执行此操作.您无法执行此操作的具体点是错误,或者是您无法证明正确代码的点.无论哪种方式,你已经学到了一些关于代码的东西,可能你已经找到了这个bug.
提示:错误消息没有错.如果需要,也请向鸭子大声朗读错误信息.
(原始海报忽略了发布错误消息,即" 为lambda声明提供的参数数量不正确 ".)
(和大脑)?
橡皮鸭调试是有效的,因为它会阻止你的大脑部分阻止你找到bug.你的大脑想要相信你写的代码是正确的,它实际上不允许你看到明显的问题.你看了代码,你的眼睛釉了一下,这"显然是正确的".不,不是.
向鸭子解释它会迫使你的大脑重新检查错误的假设,这些假设会让你相信错误的代码"显然是正确的".
请注意,它也适用于机械工程问题和填鸭.