Skip to content

Anonymous Interface Objects #4301

Description

@khalidabuhakmeh

Anonymous Interface Objects

  • Proposed
  • Prototype: Not Started
  • Implementation: Not Started
  • Specification: Not Started

Summary

Give C# developers the ability to instantiate anonymous objects that implement a specific interface without first implementing a concrete type.

Motivation

In scenarios where developers need to stub a type for unit tests, it becomes increasingly tedious to create classes that are essentially throw away. They add to the complexity of the project and ultimately increase the noise/signal ratio.

Detailed design

public interface IClient
{
    string Name { get; }
}

// single interface
var client = new IClient {
    Name = "Khalid"
};

We can also implement multiple interfaces on an anonymous type.

public interface IClient
{
    string Name { get; }
}

public interface ICustomer
{
    string AccountNumber { get; }
}

// multiple interface
var client = new IClient, ICustomer {
    Name = "Khalid",
    AccountNumber = "8675309"
};

Method implementations can be implemented using lambda methods.

public interface ICashier
{
    decimal CheckOut(Cart cart);
}

var cashier = new ICashier {
   CheckOut = (c) => cart.Total() * 0.2d;
}

Drawbacks

  • There are ways to address this issue already in the C# language that requires reflection.

Alternatives

Create stub types for every new scenario you need an interface.

Use Kotlin. Here is a working example where the khalid instance is an anonymous object that happens to implement the IGreeting interface.

image

    interface IGreeting {
        val name: String
    }

    class Default(override val name: String) : IGreeting

    fun main() {

        val csharp = Default("C# Developer")
        // an anonymous object
        // that implements IGreeting
        val khalid = object: IGreeting {
            override val name: String
                get() = "Khalid (You're Awesome)"
        }

        var folks = listOf(csharp, khalid)
        folks.forEach { println("Hello ${it.name}!") }
    }

Unresolved questions

  • What is the behavior when interfaces have conflicting properties/methods?
  • Can you define explicit interface implementations?

Design meetings

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions