Replies: 3 comments 5 replies
-
void TryDoSomething<T>(T value)
{
if (value is IHaveSomeOperation<T> hso)
{
DoSomething(hso);
}
} |
Beta Was this translation helpful? Give feedback.
1 reply
-
I think this should be solved by |
Beta Was this translation helpful? Give feedback.
4 replies
-
Use reflection (and you can use a generic dictionary for optimization): new Test().Do();
interface IHaveSomeOperation<T> { }
struct Foo : IHaveSomeOperation<Foo> { }
class Test
{
private static Dictionary<Type, Delegate> genericDict = new();
void DoSomething<T>(T value) where T : IHaveSomeOperation<T>
{
Console.WriteLine("Hello");
}
void TryDoSomething<T>(T value) where T : struct
{
if (default(T) is IHaveSomeOperation<T>)
{
var f = genericDict.ContainsKey(typeof(T)) ? (Action<T>)genericDict[typeof(T)] :
(Action<T>)(genericDict[typeof(T)] = typeof(Test)
.GetMethod(nameof(DoSomething), BindingFlags.NonPublic | BindingFlags.Instance)!
.MakeGenericMethod(typeof(T))
.CreateDelegate<Action<T>>(this));
f(value);
}
}
public void Do()
{
TryDoSomething(new Foo());
}
} |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I think it's quite difficult now to fully utilize the power of some constraint interfaces (by "constraint interfaces" I mean interfaces that are used primarily as generic constraint), especially for struct types. For example, if I want to provide different implementation for a type
T
depending on whether it implements some interfaceIHaveSomeOperation<T>
, then it would either need to box the value to call interface methods (note that this doesn't work for static abstract methods now), or to go for reflection to create a generic method bypassing constraint check. Ideally the compiler and runtime should understand some type check patterns and allow user to use generic methods/types with the same constraints that have been checked. For example:If the compiler generates the wrong code and runtime finds
T
is notIHasSomeOperation<T>
, then simply throwing an exception is acceptable.There are many constructs in the runtime that I think exists just for this reason, for example,
EqualityComparer<TKey>.Default
is to useT : IEquatable<T>
,RuntimeHelpers.IsReferenceOrContainsReferences
is to useT : unmanaged
. If we are to extend the usage of constraint interfaces, I think we should be allowed to use them in a more comfortable way, without writing something likeSomeOperationDoer<T>.Default
for eachIHaveSomeOperation<T>
interface.Also in Linq, there are many usages like
This kind of code is fine for Linq, since they only accept interface instances, which are already boxed. However, once we have structs implementing interfaces, I think we should have some better syntax to call methods without limited by constraints.
Probably related to dotnet/csharplang#3050, but here everything is known, and it is not asking for declaring a completely unknow generic type to use inside a method.
Beta Was this translation helpful? Give feedback.
All reactions