C
C#15mo ago
Starlk

❔ a question about generics

vague title because I don't know how would I word it
void Welcome<T>(T message) where T : Parent<T> { }

internal abstract record Parent<T>();

internal sealed record Child() : Parent<string>;
void Welcome<T>(T message) where T : Parent<T> { }

internal abstract record Parent<T>();

internal sealed record Child() : Parent<string>;
this might be a weird question, but how could I achieve something like this:
Welcome<Child>("string");
Welcome<Child>("string");
where the provided T type might change the message type, for example, if Child was Parent<int> then Welcome<Child>() would for an integer
15 Replies
Aaron
Aaron15mo ago
doesnt that already work as written
MODiX
MODiX15mo ago
Windows10CE#8553
REPL Result: Failure
void Welcome<T>(T message) where T : Parent<T> { }

internal abstract record Parent<T>();

internal sealed record Child() : Parent<string>;
internal sealed record Child2() : Parent<int>;

Welcome<Child>("str");
Welcome<Child2>(123);
void Welcome<T>(T message) where T : Parent<T> { }

internal abstract record Parent<T>();

internal sealed record Child() : Parent<string>;
internal sealed record Child2() : Parent<int>;

Welcome<Child>("str");
Welcome<Child2>(123);
Exception: CompilationErrorException
- Argument 1: cannot convert from 'string' to 'Child'
- Argument 1: cannot convert from 'int' to 'Child2'
- Argument 1: cannot convert from 'string' to 'Child'
- Argument 1: cannot convert from 'int' to 'Child2'
Compile: 644.114ms | Execution: 0.000ms | React with ❌ to remove this embed.
Aaron
Aaron15mo ago
oh, no i misread the answer is associated types
Starlk
Starlk15mo ago
😅 this is not real code, I'm just prototyping
Aaron
Aaron15mo ago
which C# does not yet have
Starlk
Starlk15mo ago
sad sadcat thanks for answering :)
Aaron
Aaron15mo ago
essentially associated types would let you do
public abstract interface IParent
{
public type MessageType;
}
public sealed class Child1 : IParent
{
public type MessageType = string;
}
public sealed class Child2 : IParent
{
public type MessageType = int;
}

static void Welcome<T>(T.MessageType message) where T : IParent
public abstract interface IParent
{
public type MessageType;
}
public sealed class Child1 : IParent
{
public type MessageType = string;
}
public sealed class Child2 : IParent
{
public type MessageType = int;
}

static void Welcome<T>(T.MessageType message) where T : IParent
not the real syntax of course, but shows the idea at least
Starlk
Starlk15mo ago
this looks really nice. I will have to find a walkaround for my issue
Aaron
Aaron15mo ago
sorry, the lang design people call them existential types https://github.com/dotnet/csharplang/issues/5556
GitHub
[Proposal]: Practical existential types for interfaces · Issue #555...
Practical existential types for interfaces Proposed Prototype: Not Started Implementation: Not Started Specification: Not Started Intro Previously I proposed adding some form of existential types t...
Aaron
Aaron15mo ago
associated types is the Rust (and I believe Haskell?) name for the same concept
MODiX
MODiX15mo ago
Retax#0813
REPL Result: Success
void Welcome<T, TParent>(T message) where TParent : Parent<T> { }

internal abstract record Parent<T>();

internal sealed record Child() : Parent<string>;

Welcome<string, Child>("test");
void Welcome<T, TParent>(T message) where TParent : Parent<T> { }

internal abstract record Parent<T>();

internal sealed record Child() : Parent<string>;

Welcome<string, Child>("test");
Compile: 575.137ms | Execution: 83.620ms | React with ❌ to remove this embed.
MODiX
MODiX15mo ago
Starlk#3366
REPL Result: Failure
void Welcome<T, TParent>(T message) where TParent : Parent<T> { }

internal abstract record Parent<T>();

internal sealed record Child() : Parent<string>;

Welcome<int, Child>("test");
void Welcome<T, TParent>(T message) where TParent : Parent<T> { }

internal abstract record Parent<T>();

internal sealed record Child() : Parent<string>;

Welcome<int, Child>("test");
Exception: CompilationErrorException
- Argument 1: cannot convert from 'string' to 'int'
- Argument 1: cannot convert from 'string' to 'int'
Compile: 645.970ms | Execution: 0.000ms | React with ❌ to remove this embed.
Starlk
Starlk15mo ago
Oooo This is pretty neat Nice idea Thanks! I wish the feature windows10ce mentioned becomes real
Aaron
Aaron15mo ago
yeah I assumed they didn't want that
Accord
Accord15mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.