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.
Multiple acceptable types without a shared sub-type
Compile-time checks to enforce declared type information
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.
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;
}
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.dynamic< IContractA & IContractB >?dynamic< IContractA | IContractB >?Sounds like ducktyping, is overlapping with #2146 and #154
Similarities with #13, #154, #129
This is definitely something that we want to think about.
Jon Skeet talked about this back in 2008: http://blogs.msmvps.com/jonskeet/2008/10/30/c-4-0-dynamic-lt-t-gt/
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).
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.
I wonder how close could you get using just a library. For example, I could imagine something like:
c#
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.
@svick there's one in case you're wondering ;) https://github.com/ekonbenefits/impromptu-interface
No! I want dynamic with everything that comes with it, plus static typing.
@paulomorgado ImpromptuInterface is based on dynamic meaning you can totally meta-program the entire implementation behind the interface.
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.
Most helpful comment
@paulomorgado ImpromptuInterface is based on
dynamicmeaning you can totally meta-program the entire implementation behind the interface.