Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Meta-Contracts for Dynamics (For Tooling Improvements) #3012

Closed
troyji opened this issue May 22, 2015 · 11 comments
Closed

Proposal: Meta-Contracts for Dynamics (For Tooling Improvements) #3012

troyji opened this issue May 22, 2015 · 11 comments

Comments

@troyji
Copy link

troyji commented May 22, 2015

Problem

Sometimes you are working with an object whose type you do not know, but know something about. For instance, I may be working with a dynamic object, but I may know that there will be a FirstName and LastName property. It would be nice to have a way to inform the tooling about the extra information that you know by declaring meta-contract information.

Problem domain

  • JSON Endpoints
  • Dynamic objects: Inter-language communication, Dynamic Database ORMs, etc
  • Passing anonymous objects
  • Multiple acceptable types without a shared sub-type

Primary Objectives

  • Compile-time checks to enforce declared type information
  • Intellisense support for declared type information

Solution Setup

Lets say we have a function that concatenates first a last name. The function does not care what type is passed as long as it has two properties: string FirstName and string LastName.

function string GetFullName(? entity)
{
    return entity.FirstName + " " + entity.LastName;
}

The consumer should feel free to pass any candidate type.

string fullName = GetFullName(new { FirstName = "John", LastName = "Doe" });

We could can achieve this today by making entity a type of dynamic, but we sacrifice tooling. We need a way to associate extra information with entity.

Solution

One solution would be to create an interface to serve as a contract and extend the syntax for dynamic to include the contract, dynamic<IMyContract>.

interface IEntityWithName
{
    string FirstName { get; }
    string LastName { get; }
}

function string GetFullName(dynamic<IEntityWithName> entity)
{
    return entity.FirstName + " " + entity.LastName;
}

Other Considerations

  • This problem is applicable to more than just dynamic entity types. An improvement on this solution would be to support adding the contract to any type. For instance, I may accept entities of type MyBaseType that also conform to the IEntityWithName contract.
  • The extra contract information could disappear during compilation since the goal is just to improve tooling. However, retaining the information would allow tooling improvements when consuming pre-compiled binaries as well.
  • Should multiple contracts (both A and B) be supported dynamic< IContractA & IContractB >?
  • Should alternative contracts (either A or B) be supported dynamic< IContractA | IContractB >?
@Suchiman
Copy link
Contributor

Sounds like ducktyping, is overlapping with #2146 and #154

@troyji
Copy link
Author

troyji commented May 22, 2015

Similarities with #13, #154, #129

@Pilchie
Copy link
Member

Pilchie commented May 22, 2015

This is definitely something that we want to think about.

@SolalPirelli
Copy link

Jon Skeet talked about this back in 2008: http://blogs.msmvps.com/jonskeet/2008/10/30/c-4-0-dynamic-lt-t-gt/

@bbarry
Copy link

bbarry commented May 22, 2015

You aren't really casting here or anything like that, it almost seems like a specific case of pattern matching. I think the syntaxes should align (#206).

@paulomorgado
Copy link

I have been requesting that for years, with no luck.

The only difference is that I proposed dynamic(Type) in equivalence to default(Type) because there isn't any keyword in C# that uses <Type>.

There's no need to complicate type specifications. If you need it to implement more that one interface, define one that extends those.

@svick
Copy link
Contributor

svick commented Jun 1, 2015

I wonder how close could you get using just a library. For example, I could imagine something like:

string fullName = GetFullName(new { FirstName = "John", LastName = "Doe" }.AsDuckInterface<IEntityWithName>());

where the extension method AsDuckInterface<T>() would create a wrapper class that implements the interface T and forwards the implementation to the given object.

@Suchiman
Copy link
Contributor

Suchiman commented Jun 1, 2015

@svick there's one in case you're wondering ;) https://github.com/ekonbenefits/impromptu-interface

@paulomorgado
Copy link

No! I want dynamic with everything that comes with it, plus static typing.

@jbtule
Copy link

jbtule commented Jan 9, 2016

@paulomorgado ImpromptuInterface is based on dynamic meaning you can totally meta-program the entire implementation behind the interface.

@gafter
Copy link
Member

gafter commented Mar 20, 2017

We are now taking language feature discussion on https://github.com/dotnet/csharplang for C# specific issues, https://github.com/dotnet/vblang for VB-specific features, and https://github.com/dotnet/csharplang for features that affect both languages.

@gafter gafter closed this as completed Mar 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants