[Proposal] Generic Specialization/Extension: add generic partial<>, override<> and new<> #1012
Replies: 4 comments
-
So your proposal is that the shape of the generic type would change based on the generic type arguments? That is quite counter to the nature and design of CLR generics. The members are always static and known even when the generic type is completely open. How would you propose that any of this be implemented at the CLR level? |
Beta Was this translation helpful? Give feedback.
-
AFAIK generic types are different based on arguments (as long as the arguments are structs), so But Method specializations could all be lifted into a single Method with a huge |
Beta Was this translation helpful? Give feedback.
-
Also, maybe something similar to the trick in the concepts/shape proposal might work: public class Test<T> {
public void Foo() { }
public partial<> void Baz() where T : int => Console.WriteLine("IntBaz");
}
partial<> class Test<T> where T : struct {
public void Bar() => Console.WriteLine("StructBar");
public override<> void Bar() where T : int => Console.WriteLine("IntBar");
} could be translated to: public static class Test<T> {
public interface ITest { }
public struct TestDefault : ITest { }
public interface ITestStruct<TImpl> : ITest where TImpl : ITestStruct<TImpl> {
void Bar(Test<T, TImpl> @this);
}
public struct TestExtraStruct : ITestStruct<TestExtraStruct> {
public void Bar(Test<T, TestExtraStruct> @this) => Console.WriteLine("StructBar");
}
public interface ITestInt<TImpl> : ITestStruct<TImpl> where TImpl : ITestInt<TImpl> {
void Baz(Test<T, TImpl> @this);
}
public struct TestExtraInt : ITestInt<TestExtraInt> {
public void Bar(Test<T, TestExtraInt> @this) => Console.WriteLine("IntBar");
public void Baz(Test<T, TestExtraInt> @this) => Console.WriteLine("IntBaz");
}
}
public class Test<T, TImpl> where TImpl : struct, Test<T>.ITest {
void Foo() { }
public TImpl impl = default(TImpl);
} Then this: var tString = new Test<string>();
var tDouble = new Test<double>();
tDouble.Bar();
var tInt = new Test<int>();
tInt.Bar();
tInt.Baz();
void test<T>(Test<T> t) where T : struct
=> t.Bar();
test(tDouble); // -> StructBar
test(tInt); // -> IntBar would be translated to this: var tString = new Test<string, Test<string>.TestDefault>();
var tDouble = new Test<double, Test<double>.TestExtraStruct>();
tDouble.impl.Bar(tDouble);
var tInt = new Test<int, Test<int>.TestExtraInt>();
tInt.impl.Bar(tInt);
tInt.impl.Baz(tInt);
void test<T, Timpl>(Test<T, Timpl> t) where T : struct where Timpl : struct, Test<T>.ITestStruct<Timpl>
=> t.impl.Bar(t);
test(tDouble); // -> StructBar
test(tInt); // -> IntBar |
Beta Was this translation helpful? Give feedback.
-
Related #905. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
One thing I always miss, when I go to my c# projects from c++ is template specialization, so I propose a similar mechanism be added to c# reusing the keywords
partial
,override
andnew
followed by angle brackets:partial
partial is used to extend certain generic instantiations. It works like the normal partial, but only extends the classes that satisfy the constraint.
override
override allows to specialize generic methods/classes for certain constraints/concrete types.
new
new hides more generic implementations. Specialized versions are only called, when the generic context allows it. (Probably the least usefull of the three, but here for completeness sake)
(Hopefully) useful example
The Same could be applied to
System.ValueTuple
for useful extra features, when applicable.If Concepts/shapes (#110, #164) are added to the language, much more complex scenarios are possible.
AFAIK the runtime emits specialized code for structs when it resolves generics, so it should be possible as long as the specialization is always constrained to struct. However, I would love for it to work on any type.
I chose the keywords
partial
,override
andnew
because they already exist and behave to some point similarly to the proposed versions, however other keywords likeextend
andspecialize
would of course also work.Beta Was this translation helpful? Give feedback.
All reactions