10

I want to use c# Point type as a reference type (it is a struct). I thought of having a class CPoint, which would contain a Point member. Is there any way to raise the members of the Point to act as members of the Cpoint. I am trying to avoid

cpoint.point.X;
cpoint.point.Y;

I would like to do

cpoint.X;
cpoint.Y;

as well as keep all the conversions, operators, Empty, etc.
Can this easily be done?

Baruch
  • 20,590
  • 28
  • 126
  • 201
  • why do you want/need such a wrapper? – Xint0 Jan 04 '12 at 22:37
  • 1
    @Xint0 Like I said, to use it as a reference type. – Baruch Jan 04 '12 at 22:42
  • 2
    @barunch: before doing that, consider that **there is a reason** why that kind of simple types were defined like a `structs`. One of them is, that `struct` are very fast in allocation and `Point` struct used in drawing methods, where the speed of allocation and release of it can be crucial. – Tigran Jan 04 '12 at 22:54
  • 1
    @Tigran That is true. I am not using this for drawing, however. I am using it (and Size, too) as properties of my class, not used in drawing. I want to be able to do `MyClass.Pos.X=10` and similar things. – Baruch Jan 05 '12 at 09:16
  • 1
    @barunch: so if you need just a `placeholder` create a simple class and not wrapper. May be even, if you need, for easy transformation `to/from` Point struct define implicit cast operators too. – Tigran Jan 05 '12 at 09:22
  • @baruch - I edited my answer based on your comment about accessing it via MyClass.Pos.X = 10 – Charles Lambert Jan 05 '12 at 15:37

4 Answers4

10

Something like this?

public class CPoint {
  private Point _point = new Point(0,0);
  public double X { get { return _point.X; } set { _point.X = value; } }
  public double Y { get { return _point.Y; } set { _point.Y = value; } }
  public CPoint() { }
  public CPoint(Point p) { _point = p; }
  public static implicit operator CPoint(Point p) { return new CPoint(p); }
  public static implicit operator Point(CPoint cp) { return cp._point; } 
}

EDIT: If you want to have this automatically converted to/from points, implement implicit conversions as per above. Note I haven't tested these, but they should work. More info here: http://msdn.microsoft.com/en-us/library/z5z9kes2.aspx

Chris Shain
  • 50,833
  • 6
  • 93
  • 125
5

I think the only way is to re-write and pass-through all properties, operators and methods, just like this:

public class PointReference {
  private Point point;

  public int X { get { return point.X; } set { point.X = value; } }
}

(The change of class name is intended; CPoint isn't very expressive.)

Yogu
  • 9,165
  • 5
  • 37
  • 58
  • 5
    Sure, don't use a `Point` at all, but implement it entirely yourself. – recursive Jan 04 '12 at 22:44
  • Please leave out the setter. A mutable `Point` reference type is so creepy. – CodesInChaos Jan 04 '12 at 22:57
  • 3
    @CodeInChanos: A mutable *struct* is creepy (and in my opinion in most cases a bad design). A mutable reference type, in contrast, is ok. Example might be *your location* or *the mouse position*. – Yogu Jan 04 '12 at 23:03
  • 4
    @CodesInChaos - if it wasn't mutable, it would be pointless to make it a reference type. The primary (only?) reason to make a reference wrapper for a value type, is so that you can pass around an identity whose contents can be modified (all other references receive the changed value). – ToolmakerSteve Feb 03 '17 at 16:55
4

If you need it to act like a reference type then use the ref keyword. It will allow you to pass by reference. With this you will get all of the performance benefits from it being a struct, as well as knowing specifically when you expect it to act like a reference. You can also use the out keyword to return a parameter by reference.

If you need it to be able to represent null then use a Nullable<T>

If you simply want to access is like foo.MyPoint.X then declare it as a field like so:

class Foo {
  public Point MyPoint;
}
Charles Lambert
  • 5,042
  • 26
  • 47
  • 1
    I've been programming in c# since it was first created, and never knew you could do that (use "ref" with a value type)! However, this has its limits: can't store that "reference" as an element of a collection. – ToolmakerSteve Feb 03 '17 at 16:58
0

Create a generic wrapper type.

public sealed class Ref<T> where T : struct
{
    public Ref(T value) => Value = value;

    public T Value { get; set; }
    public static implicit operator T(Ref<T> value) => value.Value;
}
Scover
  • 93
  • 9