add new method WithType to add types to a OneOf#171
add new method WithType to add types to a OneOf#171Pxtl wants to merge 1 commit intomcintyre321:masterfrom
Conversation
- also added the README to the solution
|
|
||
| {IfStruct( // constructor | ||
| $@"OneOf(int index, {RangeJoined(", ", j => $"T{j} value{j} = default")}) | ||
| $@"internal OneOf(int index, {RangeJoined(", ", j => $"T{j} value{j} = default")}) |
There was a problem hiding this comment.
why add internal to these, it will break anyone's code who has inherited from these with these constructors
There was a problem hiding this comment.
Because it's necessary. If you look in WithType, it uses the constructor of OneOfTN+1. This is also why WithType doesn't work with large size OneOfs - it can't access the constructors of the next size beyond extendedSizeLimit - 1 because those classes are located in a different assembly.
There was a problem hiding this comment.
Okay, ye I see that for this constructor now, but the $@"protected internal OneOfBase(OneOf<{genericArg}> input)1 can stay as just protected?
That way it wont effect anyone who is inheriting.
|
|
||
| {((i < extendedSizeLimit - 1) ? | ||
| // can go up to the limit before extended because OneOfT8 cannot see OneOfT9 | ||
| $@"public OneOf<{genericArg}, TNew> WithType<TNew>() => |
There was a problem hiding this comment.
This feels like a good method but, I am not sure if this interface meets the use cases I have in mind. When this is used would it not makes sense to provide a value and set the index to that value.
I think the method should at least be provided.
There was a problem hiding this comment.
I see what you mean - so in your case you're using this as a convenience object to construct a new object with a new WithType and its own value, and we're just going to throw out the old value-content.
That makes sense. I'd have to see how that works with the existing methods of OneOf. Is there some equivalent "use an existing object for a convenience-object for constructing a new one" thing to build off of?
There was a problem hiding this comment.
Thinking it over, maybe I should be redoing this as .WithTN+1 so that it becomes something like
OneOf<T1, T2, T3> myOneOf = SomeFunc();
return myOneOf.WithT4<SomeClass>();Then the case you describe could be done as a .FromTN+1; so OneOfT3 would have a .FromT4 for cases where you want to expand a T3 by one.
Or maybe just call that .FromNewType, which would make sense as a counterpart to .WithType, althought I don't know how much the .FromTN things get used.
There was a problem hiding this comment.
I'm being silly, you can't call a static method from an instance so I think the only time you could ever use .FromTN+1 would be after literally defining var myOneOf = OneOf<T1, T2, T3>.FromT4<T4>(someValue). Why would you ever do that?
There was a problem hiding this comment.
I wat thinking something like
public OneOf<T0, TNew> WithType<TNew>(TNew value) => value;
This seems to work;
{((i < extendedSizeLimit - 1) ?
// can go up to the limit before extended because OneOfT8 cannot see OneOfT9
$@"public OneOf<{genericArg}, TNew> WithType<TNew>(TNew value) => value;
":"")}Could still keep the WithType that doesn't take a value.
There was a problem hiding this comment.
Sorry I was being way too verbose in my old replies, thinking out loud. My point: in this case you're essentially constructing a new OneOf and throwing out the old value. I mean, I see how it works but I don't get what it's for.
|
Hi, thanks for using OneOf enough enough to extend it.
I think this feature would be better off in an external package, rather
than in the main project, which I'm trying to keep lean.
I can add a section to the readme with a link if you create your own
project.
…On Mon, 28 Oct 2024, 22:07 Martin Zarate, ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In Generator/Program.cs
<#171 (comment)>:
> @@ -49,13 +50,13 @@ namespace OneOf
readonly int _index;
{IfStruct( // constructor
- $@"OneOf(int index, {RangeJoined(", ", j => $"T{j} value{j} = default")})
+ $@"internal OneOf(int index, {RangeJoined(", ", j => $"T{j} value{j} = default")})
Because it's necessary. If you look in WithType, it uses the constructor
of OneOfTN+1. This is also why WithType doesn't work with large size
OneOfs - it can't access the constructors of the next size beyond extendedSizeLimit
- 1 because those classes are located in a different assembly.
------------------------------
In Generator/Program.cs
<#171 (comment)>:
> @@ -77,6 +78,12 @@ namespace OneOf
public int Index => _index;
+ {((i < extendedSizeLimit - 1) ?
+ // can go up to the limit before extended because OneOfT8 cannot see OneOfT9
+ $@"public OneOf<{genericArg}, TNew> WithType<TNew>() =>
I see what you mean - so in your case you're using this as a convenience
object to construct a new object with a new WithType and its own value,
and we're just going to throw out the old value-content.
That makes sense. I'd have to see how that works with the existing methods
of OneOf. Is there some equivalent "use an existing object for a
convenience-object for constructing a new one" thing to build off of?
------------------------------
In Generator/Program.cs
<#171 (comment)>:
> @@ -77,6 +78,12 @@ namespace OneOf
public int Index => _index;
+ {((i < extendedSizeLimit - 1) ?
+ // can go up to the limit before extended because OneOfT8 cannot see OneOfT9
+ $@"public OneOf<{genericArg}, TNew> WithType<TNew>() =>
Thinking it over, maybe I should be redoing this as .WithTN+1 so that it
becomes something like
OneOf<T1, T2, T3> myOneOf = SomeFunc();return myOneOf.WithT4<SomeClass>();
Then the case you describe could be done as a .FromTN+1; so OneOfT3 would
have a .FromT4 for cases where you want to expand a T3 by one.
Or maybe just call that .FromNewType, which would make sense as a
counterpart to .WithType, althought I don't know how much the .FromTN
things get used.
------------------------------
In Generator/Program.cs
<#171 (comment)>:
> @@ -77,6 +78,12 @@ namespace OneOf
public int Index => _index;
+ {((i < extendedSizeLimit - 1) ?
+ // can go up to the limit before extended because OneOfT8 cannot see OneOfT9
+ $@"public OneOf<{genericArg}, TNew> WithType<TNew>() =>
I'm being silly, you can't call a static method from an instance so I
think the only time you could ever use .FromTN+1 would be after literally
defining var myOneOf = OneOf<T1, T2, T3>.FromT4<T4>(someValue). Why would
you ever do that?
—
Reply to this email directly, view it on GitHub
<#171 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AACDJ6UFWXYIUMBI4LYZU5LZ52YSNAVCNFSM6AAAAABQYAN6COVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDIMBQGMYDAMZXGQ>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
The issue is functionality like this requires the use a private (made internal with this PR), what is your reason behind trying to keep it lean. Functionality like this PR are more syntactic sugar. |
I mean it's possible but the API that makes |
|
I've added an alternate typecast-based approach here: |
In order that functions that return OneOf can call other functions that return
OneOf, the
.WithType()method allows you to return existing OneOf structs butwith added types.
Note: Unfortunately because of the extended assembly design, OneOf types with
over 8 parameters cannot use
.WithType.resolves #150