views:

12235

answers:

6

Is it possible to have an anonymous type implement an interface. I've got a piece of code that I would like to work, but don't know how to do this.

I've had a couple of answers that either say no, or create a class that implements the interface construct new instances of that. This isn't really ideal, but I'm wondering if there is a mechanism to create a thin dynamic class on top of an interface which would make this simple.

public interface DummyInterface
{
    string A { get; }
    string B { get; }
}

public class DummySource
{
    public string A { get; set; }
    public string C { get; set; }
    public string D { get; set; }
}

public class Test
{
    public void WillThisWork()
    {
        var source = new DummySource[0];
        var values = from value in source
                     select new
                     {
                         A = value.A,
                         B = value.C + "_" + value.D
                     };

        DoSomethingWithDummyInterface(values);

    }

    public void DoSomethingWithDummyInterface(IEnumerable<DummyInterface> values)
    {
        foreach (var value in values)
        {
            Console.WriteLine("A = '{0}', B = '{1}'", value.A, value.B);
        }
    }
}

I've found an article Dynamic interface wrapping that describes one approach. Is this the best way of doing this?

+3  A: 

No; an anonymous type can't be made to do anything except have a few properties. You will need to create your own type. I didn't read the linked article in depth, but it looks like it uses Reflection.Emit to create new types on the fly; but if you limit discussion to things within C# itself you can't do what you want.

Marc Gravell
And important to note: properties may include functions or voids (Action) as well: select new { ... MyFunction = new Func<string,bool>(s => value.A == s) } works though you cannot refer to new properties in your functions (we can't use "A" in lieu of "value.A").
cfeduke
Well, isn't that just a property that happens to be a delegate? It isn't actually a method.
Marc Gravell
+36  A: 

No anonymous types cannot implement an Interface, the C# programming guide says: "Anonymous types are class types that consist of one or more public read-only properties. No other kinds of class members such as methods or events are allowed. An anonymous type cannot be cast to any interface or type except for object." Read more here: http://msdn.microsoft.com/en-us/library/bb397696.aspx

SpaceghostAli
+1 - Use of anonymous types should typically be limited to lambda and LINQ expressions... as soon as the *data* is being exposed to callers that need to "do something" with the object, its a very good idea to implement a concrete class.
Mark
+6  A: 

The best solution is just not to use anonymous classes.

public class Test
{
    class DummyInterfaceImplimentor : IDummyInterface
    {
        public string A { get; set; }
        public string B { get; set; }
    }

    public void WillThisWork()
    {
        var source = new DummySource[0];
        var values = from value in source
                     select new DummyInterfaceImplimentor()
                     {
                         A = value.A,
                         B = value.C + "_" + value.D
                     };

        DoSomethingWithDummyInterface(values.Cast<IDummyInterface>());

    }

    public void DoSomethingWithDummyInterface(IEnumerable<IDummyInterface> values)
    {
        foreach (var value in values)
        {
            Console.WriteLine("A = '{0}', B = '{1}'", value.A, value.B);
        }
    }
}

Note that you need to cast the result of the query to the type of the interface. There might be a better way to do it, but I couldn't find it.

ICR
You could use `values.OfType<IDummyInterface>()` instead of cast. It only returns the objects in your collection that actually can be cast to that type. It all depends on what you want.
Kristoffer L
+4  A: 

Nick,

casting anonymous types to interfaces has been something I've wanted for a while but unfortunately the current implementation forces you to have an implementation of that interface.

The best solution around it is having some type of dynamic proxy that creates the implementation for you. Using the excellent LinFu project you can replace

select new
{
  A = value.A,
  B = value.C + "_" + value.D
};

with

 select new DynamicObject(new
 {
   A = value.A,
   B = value.C + "_" + value.D
 }).CreateDuck<DummyInterface>();
Arne Claassen
+1 good answer, simple straightforward example of usage.
Maslow
A: 

The reason you could have an anonymous type impelment an interface, is because then you could pass it out and have callers know about the properties. But there is not much value in that, since you could just declre a class as easily as you could declare the interface and populate that.

Jason Coyne
+3  A: 

While this might be a two year old question, and while the answers in the thread are all true enough, I cannot resist the urge to tell you that it in fact is possible to have an anonymous class implement an interface, even though it takes a bit of creative cheating to get there.

Back in 2008 I was writing a custom LINQ provider for my then employer, and at one point I needed to be able to tell "my" anonymous classes from other anonymous ones, which meant having them implement an interface that I could use to type check them. The way we solved it was by using aspects (we used PostSharp), to add the interface implementation directly in the IL. So, in fact, letting anonymous classes implement interfaces is doable, you just need to bend the rules slightly to get there.

Banang