scriptsharp
scriptsharp copied to clipboard
Properties Set is incorrect
Hello,
I found a problem with the "set" of a property. Here is an example (I know this is not a common code but everything is possible) :
using System;
namespace Demo
{
public static class Class1
{
private static Int32 _val = 0;
public static Int32 Val
{
get { return _val; }
set
{
if (value > 0)
return;
_val = value - 100;
}
}
public static void Test()
{
Int32 v = Val++;
// ... do something with v
}
}
}
This code is converted into javascript like that:
Demo.Class1.get_val = function Demo_Class1$get_val() {
/// <value type="Number" integer="true"></value>
return Demo.Class1._val;
}
Demo.Class1.set_val = function Demo_Class1$set_val(value) {
/// <value type="Number" integer="true"></value>
if (value > 0) {
return;
}
Demo.Class1._val = value - 100;
return value;
}
Demo.Class1.test = function Demo_Class1$test() {
var v = Demo.Class1.set_val(Demo.Class1.get_val() + 1) - 1;
}
I see multiple problems here:
- The first "return" returns nothing
- The second "return" returns "value" instead of "_val". A solution would be to return a call to the "get_val" method. ex: "return Demo.Class1.get_val()"
- But... calling the get method automatically on each return is not a good solution. Because this can result in a lot of unecessary processing (the get method can be a complexe method).
A better solution, in my opinion would be: Removing all return in the set method.
And converting Int32 v = Val++; into var v = Demo.Class1.get_val(Demo.Class1.set_val(Demo.Class1.get_val() + 1) - 1); (passing a parameter to the get_val method is not a problem in javascript) The first "get_val" (on the left) can be removed if it is not necessary.
What do you think ? Thanks !
Hi,
here is another idea, not sure if it is easy to implement :
var val = 0;
function test()
{
// var b = val++;
var b = ((function() { var t = get(); set(t + 1); return t; })()); // there is only one call to "get"
// and
// var b = ++val;
var b = get(set(get() + 1)); // 2 calls to "get"
alert(b);
}
function get()
{
return val;
}
function set(value)
{
val = value;
}
Interesting that this is the first time its come up, but yes, those are some issues in the current implementation.
Not sure I like the introduce-a-closure to solve this problem. Seems heavy handed, not something that mimics the original source code, and will get more involved with more complex expressions.
I'd personally prefer to rewrite the return statements within the setter. Additionally, instead of returning the value parameter, the implementation could store a local containing the raw parameter value, and then return that. I decided against that for now simply because it also felt heavy-handed. Or get smarter and do that only if value is itself written to in the setter.
Note that in c#, having something like a = b = c sets the value of c to a as well, and not what b returns from its getter. So calling the getter to get the value to propagate as suggested by the solutions above is also incorrect.