Skip to content
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

Proposal: Modify a struct-type property directly, and allow intialization from existing instance #1347

Closed
ghost opened this issue Mar 1, 2018 · 14 comments

Comments

@ghost
Copy link

ghost commented Mar 1, 2018

Suggestion:

Use special symbol (such as <=) to modify struct-type properties directly.

Example:

Suppose we have this struct:

struct Person
{
    public int ID;
    public string Name;
    public int Points;
}

and this property:

public Person User { get; set; }

We can't directly use:
User.Points += 1;
It will not compile.

So we have to do this:

Person p = User;
p.Points += 1;
User = p;

I suggest to use this syntax instead to do the same job as the previous code:

User <= Points += 1;

Another approach:

it will be easier if the Type initializer can initialize the new instance by the values of another instance:

User = User {Points += 1};

In this syntax we allow two new things:
1- use an existing instance instead of a "new Person ()".
2- use the += inside the {} because ID have a previous value and can be modified.

The last syntax can be re-written as:

User += {Points += 1};

@svick
Copy link
Contributor

svick commented Mar 1, 2018

Is using ref-returning property not acceptable for you?

@ghost
Copy link
Author

ghost commented Mar 1, 2018

How can I use it with existing properties in framework?
If the problem is about programmer-defined properties and structures, one can find many other ways to solve the problems.

@HaloFour
Copy link
Contributor

HaloFour commented Mar 1, 2018

Value copy semantics is the distinguishing characteristic of structs. You're not updating a property of that struct, you are overwriting the entire thing. I think that glossing over this would encourage using structs in ways that are discouraged.

@svick
Copy link
Contributor

svick commented Mar 1, 2018

How can I use it with existing properties in framework?

You can't. But what framework properties return mutable value types that you want to modify often?

@ghost
Copy link
Author

ghost commented Mar 1, 2018

The one that I recall, although it's not about structs is:
textBox1.Lines[0] = "abc";
This will compile, but will not affect the textbox!
acourding to my suggesion it can be re-written as:
textBox1.Lines<=[0] = "abc";
Or:
textBox1.Lines = textBox1.Lines {[0] = "abc"};

Note that this matter affects third-party codes as well: COM, NuGet .... etc.

@ghost
Copy link
Author

ghost commented Mar 1, 2018

Addition: Any method that returns a Point, a Size, or a Rectangle in framework face the same problem, and it is widely used. There are many similar structs like Padding and others.

@orthoxerox
Copy link

Withers (#162) could be extended to work not only with immutable types, but with struct properties as well: User = User with { .Points += 1 }

@HaloFour
Copy link
Contributor

HaloFour commented Mar 1, 2018

@MohammadHamdyGhanem

Indeed, that has nothing to do with structs. It will happen with any property that returns a disconnected value.

These situations should be sufficiently rare and since you'd need a separate syntax anyway I don't see why it's such a problem to explicitly have to reassign the property. Again, in the case with TextBox.Lines, you are rewriting the entire contents of the textbox based on the array, regardless of whether you only modified a single element. I think it's important for the developer to understand that.

@jnm2
Copy link
Contributor

jnm2 commented Mar 1, 2018

The only times I can recall having to deal with setting struct properties:

  • Once in a great while obj.Size.Width = 42 which I resolve with extension methods, so obj.Size = obj.Size.WithWidth(42). I like that because it doesn't gloss over the fact (like HaloFour said) that there is no way to set just the width; set_Size must be called. I wouldn't mind a with syntax to save me the trouble of maintaining extension methods.

  • Slightly more commonly I'll have builder structs in a dictionary and have to do an extra hash lookup to store the modified struct back into the dictionary. To svick's point, we now have https://github.com/dotnet/corefx/issues/25189 in 2.1 (https://github.com/dotnet/corefx/issues/20684 for ordinary Dictionary still open) which addresses that.

@ghost
Copy link
Author

ghost commented Mar 1, 2018

@orthoxerox

Withers (#162#162, Champion "pattern-based with expressions") could be extended to work not only with immutable types, but with struct properties as well: User = User with { .Points += 1 }

I agree. But it can be more compact like this:
User += { .Points += 1 }

@orthoxerox
Copy link

@MohammadHamdyGhanem Or User with= { ... }? :trollface:

@ghost
Copy link
Author

ghost commented Mar 2, 2018

With= does not imply that the object should keep its old values.

@jnm2
Copy link
Contributor

jnm2 commented Mar 2, 2018

@MohammadHamdyGhanem Yes, it does. If the word with appears, it means all other previous values are preserved.

@AustinBryan
Copy link

Why not use <- or something else instead of <= which already means something and could cause conflicts.

Besides that, just use a class..

@ghost ghost closed this as completed Mar 4, 2019
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants