1

It's been concerning me that the duck-typing libraries I can find for C# all breaks object identity, ie Object.ReferenceEquals returns false for a duck-typed object and its original object.

It seems impossible to achieve a wrapper/proxy-less solution in C#, esp. given that it's a fundamental OO concept, but hoping I'm wrong, anyone know if there is a way, especially in later language versions?

Edit, a code example was requested:

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));
    }
}
ciscoheat
  • 3,719
  • 1
  • 35
  • 52
  • 4
    Could you give an example of what you're actually trying to achieve? For example, could you not just use `dynamic` from C# 4? – Jon Skeet May 12 '13 at 16:27
  • 2
    I'm with @Jon. Dynamic is .net's duck typing metaphor, it certainly wouldn't cause object.ReferenceEquals to fail. – Tony Hopkinson May 12 '13 at 16:29
  • 2
    @TonyHopkinson :) "I'm with Jon" ... Of course you are, who's not :) It's Jon :))) – Dimitar Dimitrov May 12 '13 at 16:34
  • I'm making a DCI library for C# (https://github.com/ciscoheat/ivento-dci), and there can be many interfaces for an object then, so I was hoping to duck type the objects to them instead of cluttering the classes with interface types. But since DCI requires object identity to be intact, it's not possible with what I've found so far. Dynamic is an option, but there can be many constructors for a Context object, so it's nice to have some type safety/implementation hints there. – ciscoheat May 12 '13 at 16:38
  • 1
    @DimitarDimitrov. If Jon said he was agreeing with me, that would indeed be more of a surprise. – Tony Hopkinson May 12 '13 at 21:57
  • @ciscoheat. Some code would be useful, suffering a failure to understand what you are getting at. Reference could never be equal from what you are saying. – Tony Hopkinson May 12 '13 at 22:06
  • Sorry about the delay, added a code example now. – ciscoheat Jun 16 '13 at 23:22

2 Answers2

1

From what I understand, given a reference to an object whose type is unknown, but is expected to have a Quack method with a given signature, you want to produce an something with a Quack method of like signature that will call the appropriate method in the original object. You further desire that the latter object should compare reference-equal to the original. The things you seek are not possible.

You may, however, be able to define a Quack extension method either on Object or on a generic type, which will examine the type of its argument, see if it has a Quack method, and call it if so. Every single method signature of interest would require a separate boilerplate method, but it would probably be possible to have them boil down to about 4-5 lines of boilerplate code apiece (calling a common method to use Reflection to find the appropriate member in the type and cache the result).

supercat
  • 77,689
  • 9
  • 166
  • 211
1

With the exactness of your question, the answer to it is no. You cannot.

Object.ReferenceEquals is a direct comparison between two object's in-memory addresses.

It's for this reason that the following code writes False to the console window, even though, logically you may think it should write True:

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

In the case of the myVar, the result is False because the value-type is boxed into an object instance that points to myVar.

The Duck Typing itself creates a form of box around your object.

If you implemented the Duck Typing yourself, you could have your own ReferenceEquals method that takes advantage of this boxing mentality and correctly unboxes the original object before doing the ReferenceEquals comparison.