Proposal: Function overloading for types that do not share a base. #4223
-
I have an idea for a language feature but have no experience in this domain, so I thought I would start a discussion first. I have often seen scenarios where C++ style template would significantly reduce the amount of boilerplate required in some circumstances. Having no generic constraints however could be problematic with respect to code quality, unless C++ style concepts are implemented, which I do not think is on the table. A possible alternative could be to state which types you want to overload a function with, eg. public static Add<T>(BigRational rational, T integer)
where T overloads: BigInteger, long, ulong
{
// use var in code
} this would then be equivalent to public static Add(BigRational rational, BigInteger integer)
{
// verbatim copy of the code in generic version
}
public static Add(BigRational rational, long integer)
{
// verbatim copy of the code in generic version
}
public static Add(BigRational rational, ulong integer)
{
// verbatim copy of the code in generic version
} Another application could be to unify APIs for different types. Consider the following scenario public class MyWorker : IMyWorker
{
public int DoWork() {...}
}
public class YourWorker
{
public int Work() {...}
}
public static class MyExtensionMethods
{
public static int DoWork(this YourWorker self)
{
return self.Work() {...};
}
}
public class static SomeClass
{
public static int UseWorker<TWorker>(TWorker worker)
where T : IWorker
where T overloads: MyWorker, YourWorker
{
return 42 * worker.DoWork();
}
}
public static class SomeClass
{
// regular generic method
public static int UseWorker<TWorker>(TWorker worker)
where T : IWorker
{
return 42 * worker.DoWork();
}
// avoids potential virtual call
public static int UseWorker(MyWorker worker)
{
return 42 * worker.DoWork();
}
// calls extension method
public static int UseWorker(YourWorker worker)
{
return 42 * worker.DoWork();
}
} this also makes various other permutations possible. Potential problems: |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments
-
I believe that the exploration around roles or shapes would cover these use cases. This is something that the language team as expressed interest in exploring over the next few cycles and hopefully fleshing out a feature (or multiple features) that would enable these kinds of scenarios, either implicitly or through some "witness type" that would act as the glue. In either case the goal is to expand on generics and generic constraints with something like C++ concepts where a type could be considered to meet the concept as long as the compiler could resolve the required members. |
Beta Was this translation helpful? Give feedback.
-
This could be solved with C#10's discriminated unions: public static Add<T>(BigRational rational, Union<BigInteger, long, ulong> integer)
{
} |
Beta Was this translation helpful? Give feedback.
-
It corms be achieved now with Source Generators.
…On Sun, 13 Dec 2020, 01:54 Unknown6656, ***@***.***> wrote:
This could be solved with C#10's discriminated unions:
public static Add<T>(BigRational rational, Union<BigInteger, long, ulong> integer)
{
}
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#4223 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ADIEDQIK4NROHADO5DV2TULSUQNEJANCNFSM4UY3TTBA>
.
|
Beta Was this translation helpful? Give feedback.
-
The code looks F#-ish. The design concept of C# and F# are different. C# is more close to CLR features. |
Beta Was this translation helpful? Give feedback.
I believe that the exploration around roles or shapes would cover these use cases. This is something that the language team as expressed interest in exploring over the next few cycles and hopefully fleshing out a feature (or multiple features) that would enable these kinds of scenarios, either implicitly or through some "witness type" that would act as the glue. In either case the goal is to expand on generics and generic constraints with something like C++ concepts where a type could be considered to meet the concept as long as the compiler could resolve the required members.