views:

364

answers:

5

I am wondering what type the 'value' keyword in a property takes.

so:

public class Test
{
    string _numberAsString;
    int _number = -1;

    public Test() {}

    public string NumberAsString
    {
        get { return _numberAsString; }
        set { _numberAsString= value; }
    }

    public int Number
    {
        get { return int.Parse(_numberAsString); }
        set { _number = value; }
    }
}

//elsewhere
Test t = new Test();
t.Number = 5;

Now, this doesn't compile, as I'd expect. The type of 'value' is determined by the return type of the property, is that correct? I couldn't find anything to that effect, perhaps it's too obvious (I haven't read the language specs, presumably there's something in there).

I ask, because I would like to set the property with a type that is then converted into the type of the getter. I suppose this doesn't really make sense.

It seems I will have to achieve this by creating a couple of methods.

A: 

I'm confused by your question because get and set are implicitly the same type. What error do you get when you try to compile this?

Greg D
+2  A: 

Yes, the type of 'value' is determined by the return type of the property. What exactly are you trying to accomplish? Do you want to be able to set either Number or NumberAsString to a valid value and get a result back out from either property?

If that's the case you need to do something like this:

public class Test
{
   string _numberAsString;
   int _number = -1;

   public Test() {}
   public string NumberAsString
   {
       get { return _numberAsString; }
       set { _numberAsString= value; }
   }
   public int Number
   {
       get { return int.Parse(_numberAsString); }
       set { _numberAsString = value.ToString(); }
   }
}

This would allow you to do this:

Test t = new Test();
t.Number = 5;
Console.WriteLine(t.NumberAsString); // should print out "5"
t.NumberAsString = "5";
Console.WriteLine(t.Number); // should print out "5"

You can't have a get and a set for a property that take different types. The only option you have is to store it internally as one type and then in either the get or the set (or both) perform the conversion from one type to another.

Scott Dorman
+2  A: 

The type of the value in the setter is the type of the property - you cannot pass a string to a property that is an int, this must first be parsed to an int.

Strings in .net cannot be coerced into any other type (in the way perl, awk and many other dynamic languages allow) they can only be treated as string, or as their parent class object.

you could do the follwoing:

private int _number;
private string  _numberAsString;

public string NumberAsString
{
    get { return _numberAsString; }
    set { LinkedSet(value); }
}

public int Number
{
    get { return _number; }
    set { LinkedSet(value); }
}


private void LinkedSet(string s)
{
    this._number = int.Parse(s);
    this._numberAsString = s;
}  

private void LinkedSet(int i)
{
    this._numberAsString = i.ToString();
    this._number = i;
}

obviously the NumberAsString setter can throw a FormatException the Number setter cannot.

I do not recommend this in general though unless you really need to avoid converting the number to a string and the string to a number on a regular basis (at which point you can make the setters lazy in their evalition of the linked value - albeit changing the semantics of the exception from on set of the string to on get of the int - likely to be at best annoying or at worst a nasty bug.

ShuggyCoUk
A: 

It doesn't make sense, to me, to allow a setter on NumberAsString.

Why not this?:

public class Test
{
   int _number = -1;

   public Test() {}
   public string NumberAsString
   {
       get { return _number.ToString(); }
   }
   public int Number
   {
       get { return _number; }
       set { _number= value; }
   }
}
Chris Martin
A: 

Why not just do

Test t = new Test();
t.Number = 5;
Console.WriteLine(t.Number.ToString());

It strikes me that you're trying to be crafty for no real reason.

I think you are trying to use a property here when a method would be more appropriate. A property isn't supposed to have any unforeseen side effects, which this would by performing a type conversion on it (if it were possible).

steve_c