Page MenuHomePhabricator

C# better syntaxes for new Eina.Size2D and new Eina.Position2D
Open, Incoming QueuePublic

Description

It would be nice to improve the helper available in our EFL# binding so that user could just give a tuple for a Size2D or Position2D or any simpler construction that wouldn't require less code typing. Not to sure of what would be the best solution here, but improvement would be great.

cedric created this task.Sat, Nov 23, 7:58 AM

This could be done by adding an implicit operator from a tuple, like the snippet below. Also we could add the Deconstruct method easily unpack into tuples too.

using System;

public struct Point2D
{
	public Point2D(int x, int y)
	{
		X = x;
		Y = y;
	}
	
	public int Y { get; set; }
	public int X { get; set; }
	
	// Convert from tuple
	public static implicit operator Point2D((int x, int y) p) {
		return new Point2D(p.x, p.y);
	}
	// Deconstruct into tuple
	public void Deconstruct(out int x, out int y) {
		x = X;
		y = Y;
	}
}

public class Program
{	
	public static void Main()
	{
		Point2D p = (1, 2);
		(int x, int y) = p;
	}
}

Source: https://peakup.org/blog/advanced-tuple-techniques-in-c/

This looks really helpful indeed.
Are we targeting C# 7?
And does this work on mono and dotnet too?

Looks like mono does not support it.

https://github.com/mono/mono/blob/369806e3e6941f472c4d9d239ae76936ebe5aa39/mcs/mcs/tuples.cs#L590

We could still go with creating structs from tuples (which seems to be the original scenario @cedric asked for)

lauromoura assigned this task to jptiz.Mon, Dec 2, 7:52 AM

I think being able skip the new Point2D(...) in parameters was the main concern of people at EDD, so whatever we do to help will be welcome :)
So if we only support conversion FROM tuples and not TO tuples, I think that's still an improvement.

That said, this "NotImplemented" is a runtime thing, right? Why don't we just implement everything and let the users decide if they want to use them, depending on what runtime they want to use? (.net, mono, ...)? Can we do that?

That said, this "NotImplemented" is a runtime thing, right? Why don't we just implement everything and let the users decide if they want to use them, depending on what runtime they want to use? (.net, mono, ...)? Can we do that?

It's actually in the mono compiler, so if we try to generate EFL# code with Deconstruct calls (not definitions) it would ka-boom.

One option is to generate the Deconstruct method but without invoking it (ifdef'ing the tests?).

One option is to generate the Deconstruct method but without invoking it (ifdef'ing the tests?).

Yeah, that's what I was thinking about. We ifdef the tests when the compiler is mono, and the users should do the same. It's not our fault if that particular compiler does not support all features! :D

jptiz added a comment.EditedTue, Dec 3, 12:35 PM

I was working on this task, but then I ran into a problem with generating tuples for structs with too many fields. More specifically, after generating:

public static implicit operator MyType((fields...) tuple) {
    return new MyType{...};
}

The mcs compiler crashes if tuple size is 8 or more (i.e. the struct has 8 or more fields), but it compiles fine with csc.
A temporary (I hope) workaround would be to limit the operator's generation for structs with <=7 (considering known compatibility) or <=4 (considering a reasonable tuple size for use cases such as Point/Size/Rect/ColorRGBA) fields only. How does that sound?

I think limiting them to a reasonable size makes sense.

I think so too, yeah. Accessing member of an 8-tuple is going to be a pain anyway :D