-
Notifications
You must be signed in to change notification settings - Fork 165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add new method WithType to add types to a OneOf #171
base: master
Are you sure you want to change the base?
Conversation
- also added the README to the solution
@@ -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")}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
@@ -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>() => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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