Should we allow switch on generic? #2761
Replies: 11 comments
-
I commonly have this case, and I need to do the horrific switch (typeof(T))
{
case var t when t == typeof(string):...
case var t when t == typeof(int):...
} However my preferred solution would be switching on type which is already a proposal. #356. I feel this makes more sense conceptually than switching on a type parameter |
Beta Was this translation helpful? Give feedback.
-
#356 ? |
Beta Was this translation helpful? Give feedback.
-
@YairHalberstadt @ufcpp I already did T Parse<T>(object s)
{
switch(typeof(T))
{
case typeof(string):
return s; // Error, must use `return (T)s;` or `return (T)((object)s)`
//...
default:
return default(T);
}
} I wish that T Parse<T>(object s)
{
switch(T)
{
case string:
return s; // No error
//...
default:
return default(T);
}
} And it also more verbose that we need to |
Beta Was this translation helpful? Give feedback.
-
Currently the language has no concept of inferring the type of a generic type parameter. If it did, maybe the following ought to work as well: T M(T t)
{
if (t is string s) //T is a supertype of string
return "hello + s";
} For example. However I think that is a much bigger feature than just switching on T, and I'm not sure the benefits are significant enough to make it worth it. |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
Whilst technically it does call into reflection, it should only need the Type APIs , which are very fast, so I don't think that should be a problem. |
Beta Was this translation helpful? Give feedback.
-
What would be useful for me on occasions is the ability to use switch with generics in the following way: class C<T1, T2>
{
private T1 _t1;
private T2 _t2;
public T GetValueOf<T>()
=> T switch {
T1 => _t1,
T2 => _t2,
_ => throw new InvalidOperationException()
};
} such that eg in the first branch, the compiler knows that However, I suspect this is real edge-case stuff and that the ROI of implementing it would be low. |
Beta Was this translation helpful? Give feedback.
-
In such a edge case, class C<T1, T2>
{
private T1 _t1;
private T2 _t2;
public T GetValueOf<T>()
{
if (typeof(T) == typeof(T1)) return Unsafe.As<T1, T>(ref _t1);
if (typeof(T) == typeof(T2)) return Unsafe.As<T2, T>(ref _t2);
throw new InvalidOperationException();
}
} |
Beta Was this translation helpful? Give feedback.
-
I've taken to using an extension method: public static T ItemAs<T>(this object? obj)
=> obj is T cast
? cast
: throw new InvalidOperationException($"Failed to cast item to type {typeof(T)}"); and then using it like: public T GetValueOf<T>()
=> T switch {
var t where t == typeof(T1) => _t1.ItemAs<T1>(),
var t where t == typeof(T2) => _t2.ItemAs<T2>(),
_ => throw new InvalidOperationException()
}; It's easy to work around. It just feels clunky. But in SuccincT, which uses generics far far more than I've ever used it before, there's along around a dozen such cases, even there. So it's a serious edge case and I'll live with the remaining clunkiness if/when #356 is implemented. |
Beta Was this translation helpful? Give feedback.
-
The |
Beta Was this translation helpful? Give feedback.
-
@ufcpp There are always exist a workaround for |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Beta Was this translation helpful? Give feedback.
All reactions