Question

I have an immutable struct and would like to keep it immutable, but also allow schematics like var p2 = p1.v = 3. I thought that the following might work, but it appears not:

public struct Number {
    readonly int n;

    public int N {
        get{ return n; }
        set{ return new Number(value); }
    }

    public Number(int newN) {
        n = newN;
    }
}

Is there any way to get var p2 = p1.v = 3 or var p2 = (p1.v = 3) to work?

Was it helpful?

Solution

No, there is no syntax like this that will work. Setters are, well, setters, not a way to get something.

OTHER TIPS

First of all you want to do something that no one will be able to read. If you structure is immutable what one should expect as result of p1.v = 3? Obviously p1 should not change, no one expect setter to return value... the only reasonable behavior would be to see an exception "This object is immutable", but than lack of setter would be much better indication of the property being read only....

Possibly you trying to implement something like fluent interface which is much more common:

 var newValue = oldValue.WithOneProperty(5).WithOtherProperty(3);

 class Number 
 {
   int oneProperty;
   int otherProperty;
   Number WithOneProperty(int v) { return new Number(v, this.otherProperty); }     
   Number WithOtherProperty(int v) { return new Number(this.oneProperty, v); }
 }

You should only return values from getters.

I think there is a valid use for this with one-time-tokens or keys. I used some of the code here to generate this:

public class MyController : Controller
{
    private static string m_oneTimeKey = "this key hasn't been initialised yet";

    private string oneTimeKeyGet()
    {
        // Return the last key
        string returnValue = MyController.m_oneTimeKey;

        // Generate a new random key so the one we return can't be reused
        var m_oneTimeKey = GetRandomString();
        return returnValue;
    }

    private string oneTimeKeySet()
    {
        // Generate a new random key
        var newValue = GetRandomString();
        m_oneTimeKey = newValue;
        return newValue;
    }

    private string GetRandomString()
    {
        var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        var random = new Random();
        var returnValue = new string(
            Enumerable.Repeat(chars, 8)
                      .Select(s => s[random.Next(s.Length)])
                      .ToArray());
        return returnValue;
    }

And then I use it with:

 var myURL = "/Index?id=" + ID + "&key=" + oneTimeKeySet();

And within the ActionResult I can verify if this is the one time call with:

public ActionResult Index(Guid id, string key)
    {
        if (key == oneTimeKeyGet() {
            ....
        }
    }
}

I've actually gone a step further and I also have a static key that is passed between functions that is also checked for in the if in the ActionResult.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top