Announcement

Collapse
No announcement yet.

[CLOSED] [2710] [16.0] [External] [ObjectLiteral] properties camel-cased when they shouldn't be

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    [CLOSED] [2710] [16.0] [External] [ObjectLiteral] properties camel-cased when they shouldn't be

    The properties of an [External] [ObjectLiteral] type that are set by a constructor are set with camel-cased names but this casing convention is not applied to properties accessed outside of the constructor - eg.

    public class Program
    {
        public static void Main()
        {
            var x = new PersonDetails(123, "Bob");
            Console.WriteLine("Name: " + x.Name); // Doesn't work ("name" is set but "Name" isn't)
    
            x.Name = "Bob";
            Console.WriteLine("Name: " + x.Name); // This shows the expected value
        }
    }
    
    [External]
    [ObjectLiteral]
    public class PersonDetails
    {
        public PersonDetails(int key, string name)
        {
            Key = key;
            Name = name;
        }
        public int Key { get; set; }
        public string Name { get; set; }
    }
    The problem is obvious when you look at the generated JavaScript -

    Bridge.define("Demo.Program", {
        main: function Main() {
            var x = { key: 123, name: "Bob" }; // <--- PROBLEM HERE ("name" instead of "Name")
            System.Console.WriteLine(System.String.concat("Name: ", x.Name));
    
            x.Name = "Bob";
            System.Console.WriteLine(System.String.concat("Name: ", x.Name));
        }
    });
    Available at: https://deck.net/34707ebb9d31d281e0c61b44f0262888

    #2
    Hi,

    I don't think that it is a bug because Bridge doesn't know how constructor arguments will be used inside the body (frankly, it is not recommended to use ctor with the body because it's code will be ignored). Bridge doesn't map arguments to properties. In your case, Bridge just uses arguments names (it is not convention problem).

    Therefore, use Template on the constructor or just object create initializers.
    We will think about to raise an exception if constructor with body is used for object literal with plain mode

    Comment


      #3
      I agree that it's a technique that's best avoided but sometimes it can be useful.

      I can also see your other point the argument casing.. I guess that it's just unfortunate that it basically worked in 15.7.0 but doesn't in 16.0, though I completely understand why.

      I think that an exception or a warning might be useful - it's better to know that you're doing something that probably won't work than to think that it's alright and then wonder what went wrong!

      On a slight tangent, I've noticed that the default ToString implementation for classes seems to return a JSON representation of the object - which is very handy! Is this documented behaviour? Or is there a method that is intended to do this? I was sure that I'd seen a ToJSON method somewhere but I'm not sure where..

      Comment


        #4
        On a slight tangent, I've noticed that the default ToString implementation for classes seems to return a JSON representation of the object
        Hi ProductiveRage – Are you explicitly calling .ToString() or are you seeing this json formatted string when using Console.WriteLine?

        If you're explicitly calling .ToString(), it should still emit as [object Object], just like the browser console.

        If you are Console.WriteLine'ing an object, by default as of Bridge 16, Bridge.Console will emit as a json formatted string. I think this is what you're seeing.

        https://deck.net/949b0e5bbcc7343e9518dbde27d7b75a

        public class App
        {
            public static void Main()
            {
                var p = new Person { Name = "Frank" };
        
                var msg = p.ToString();
        
                Console.WriteLine(msg);
        
                Console.WriteLine(p);
            }  
        }
        
        public class Person
        {
            public string Name { get; set; }
        }
        The recent Bridge.Console improvements were logged in Issue #1994.
        Last edited by geoffrey.mcgill; 2017-05-15 @ 11:05 PM.

        Comment


          #5
          I was doing this:

          public class Program
          {
              public static void Main()
              {
                  var x = new PersonDetails(123, "Bob");
                  Console.WriteLine(x.ToJSON());
              }
          }
          
          public class PersonDetails
          {
              public PersonDetails(int key, string name)
              {
                  Key = key;
                  Name = name;
              }
              public int Key { get; set; }
              public string Name { get; set; }
              public string ToJSON()
              {
                  return Script.Write<string>("this");
              }
          }
          (https://deck.net/2b1ecbf273d84078b6577f708e8abffb)

          Comment


            #6
            Fix for issue #2710 merged into master branch and will be included in the next Bridge.NET release.

            The following checks now applied to [External] [ObjectLiteral] (the same rules as for [ObjectLiteral]):
            • "[ObjectLiteral] does not support virtual methods: {0}";
            • "[ObjectLiteral] class (plain mode) does not support Bridge.ObjectCreateMode parameter in a custom constructor: {0}";
            • "[ObjectLiteral] class (plain mode) does not support custom constructors with parameters other than with ObjectLiteralAttribute properties: {0}";
            • "[ObjectLiteral] with Plain mode cannot be inherited from [ObjectLiteral] with Constructor mode: {0}";
            • "[ObjectLiteral] with Constructor mode should be inherited from a class with the same options: {0}";
            • "[ObjectLiteral] interface does not support overloaded methods: {0}";
            • "[ObjectLiteral] interface does not support events: {0}";
            • "[ObjectLiteral] does not support explicit interface member implementation: {0}";
            • "[ObjectLiteral] should implement an interface which must be object literal also: {0}";

            Comment

            Working...
            X