Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a C# equivalent to Ruby's `respond_to?`?

Tags:

c#

dynamic

I'm writing a simple wrapper to "duck" a dynamic object against a known interface:

interface IFoo { string Bar(int fred); }

class DuckFoo : IFoo
{
    private readonly dynamic duck;

    public DuckFoo(dynamic duck)
    {
        this.duck = duck;
    }

    public string Bar(int fred)
    {
        return duck.Bar(fred);
    }
}

This works fine if the dynamic object can respond to the Bar signature. But if it cannot this fails only when I call Bar. I would prefer if it could fail faster, i.e., with argument validation upon construction of the DuckFoo wrapper. Something like this:

public DuckFoo(dynamic duck)
{
    if(/* duck has no matching Bar method */)
        throw new ArgumentException("duck", "Bad dynamic object");
    this.duck = duck;
}

In Ruby there is a respond_to? method that can be used to test if an object "has" a certain method. Is there a way to test that with dynamic objects in C# 4?

(I am aware that even with this check the Bar call could fail later on because the dynamic nature of the duck lets it stop responding to methods later on.)

like image 386
R. Martinho Fernandes Avatar asked Dec 09 '09 23:12

R. Martinho Fernandes


People also ask

What is C--?

C-- is a "portable assembly language ", designed to ease the implementation of compilers that produce high-quality machine code. This is done by delegating low-level code-generation and program optimization to a C-- compiler.

What is the type system in C?

Type system. The C-- type system is deliberately designed to reflect constraints imposed by hardware rather than conventions imposed by higher-level languages. In C--, a value stored in a register or memory may have only one type: bit vector.

What does C--stand for?

C-- ( pronounced cee minus minus) is a C -like programming language. Its creators, functional programming researchers Simon Peyton Jones and Norman Ramsey, designed it to be generated mainly by compilers for very high-level languages rather than written by human programmers. Unlike many other intermediate languages,...

Is there a C++ interpreter for C++?

Probably. There are several for c++. See Have you used any of the C++ interpreters (not compilers)? for examples. Certainly cint will eat nearly any c code with good results, and tcc is so fast that you can use it like a interpreter.


2 Answers

You could check the methods available on the object being wrapped using Reflection, at construction time.

Just call Type.GetMethods() on the interface and the type being passed in, and make sure the appropriate methods exist.


Edit:

As suggested by itowlson, there is an option for handling dynamic types, as well. If you check for the existance of the IDynamicMetaObjectProvider interface on the passed object, you could then call IDynamicMetaObjectProvider.GetMetaObject().GetDynamicMemberNames(), and use this information.

If the interface does not exist, you could just revert to Type.GetMethods().

This should handle the "dynamic" types, as well.

like image 108
Reed Copsey Avatar answered Sep 28 '22 15:09

Reed Copsey


I don't know of a definite way to check if the object provides a specific method. Of course, you could use reflection, but that only works if the object is a .NET object. If you are sure that it is, than, as already said, no problem, just call GetType() on the object and check with GetMethod().

On the other hand, as you said yourself, even a check at this point doesn't guarentee that the call to the method will succeed later on, so I think that the check is useless. Just let the call fail when it actually does. It could also be that your check says the object doesn't provide a specific method, but later on, when you would actually call it, it does.

like image 25
Maximilian Mayerl Avatar answered Sep 28 '22 15:09

Maximilian Mayerl