一个用于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));
    }
}

一个用于c#的duck-typing库,它不会破坏对象标识

据我所知,给定对类型未知的对象的引用,但期望具有具有给定签名的Quack方法,您希望生成具有类似签名的Quack方法的东西,该方法将调用原始对象中的适当方法。您进一步希望后一个对象应该与原始对象比较参考相等。你追求的东西是不可能的。

但是,您可以在Object或泛型类型上定义Quack扩展方法,这将检查其参数的类型,查看它是否具有Quack方法,如果有,则调用它。每个感兴趣的方法签名都需要一个单独的样板方法,但是很可能将它们简化为大约4-5行样板代码(调用一个通用方法来使用Reflection在类型中找到适当的成员并缓存结果)。

的准确性你的问题,它的答案是。你不能。

Object.ReferenceEquals是两个对象的内存地址之间的直接比较。

正是由于这个原因,下面的代码将False写入控制台窗口,尽管从逻辑上讲,您可能认为它应该写入True:

int myVar = 0;
Console.WriteLine(Object.ReferenceEquals(myVar, myVar))

myVar的情况下,结果是False,因为值类型被装箱到指向myVarobject实例中。

Duck Typing会在你的对象周围创建一个方框。

如果您自己实现了Duck Typing,那么您可以拥有自己的ReferenceEquals方法,该方法可以利用装箱的思想,并在进行ReferenceEquals比较之前正确地打开原始object的装箱