一个用于c#的duck-typing库,它不会破坏对象标识
本文关键字:标识 对象 duck-typing 一个 用于 | 更新日期: 2023-09-27 18:13:09
我一直担心,我可以为c#找到的鸭子类型库都打破了对象身份,即Object.ReferenceEquals
为鸭子类型对象及其原始对象返回false。
在c#中实现无包装器/代理的解决方案似乎是不可能的,特别是考虑到它是一个基本的面向对象概念,但希望我是错的,有人知道是否有一种方法,特别是在后来的语言版本中?
编辑,请求代码示例:
public class MyClass
{
private SomeInterface _someInterface;
// Dynamic is possible here but the type safety is helpful
// when having multiple constructors, for example.
public MyClass(AnotherClass c)
{
_someInterface = c.ActLike<SomeInterface>();
Trace.Assert(object.ReferenceEquals(c, _someInterface));
}
}
据我所知,给定对类型未知的对象的引用,但期望具有具有给定签名的Quack
方法,您希望生成具有类似签名的Quack
方法的东西,该方法将调用原始对象中的适当方法。您进一步希望后一个对象应该与原始对象比较参考相等。你追求的东西是不可能的。
Object
或泛型类型上定义Quack
扩展方法,这将检查其参数的类型,查看它是否具有Quack
方法,如果有,则调用它。每个感兴趣的方法签名都需要一个单独的样板方法,但是很可能将它们简化为大约4-5行样板代码(调用一个通用方法来使用Reflection在类型中找到适当的成员并缓存结果)。
与的准确性你的问题,它的答案是不。你不能。
Object.ReferenceEquals
是两个对象的内存地址之间的直接比较。
正是由于这个原因,下面的代码将False
写入控制台窗口,尽管从逻辑上讲,您可能认为它应该写入True
:
int myVar = 0;
Console.WriteLine(Object.ReferenceEquals(myVar, myVar))
在myVar
的情况下,结果是False
,因为值类型被装箱到指向myVar
的object
实例中。
Duck Typing会在你的对象周围创建一个方框。
如果您自己实现了Duck Typing,那么您可以拥有自己的ReferenceEquals
方法,该方法可以利用装箱的思想,并在进行ReferenceEquals
比较之前正确地打开原始object
的装箱