다음을 통해 공유


Bean Style properties in J#

In Visual Studio 2005 release, J# supports writing properties in Java bean style also. How are they different from the normal .net style properties of J#? Following is the comparison …

Bean Style Properties

.Net Style Properties                           

Declaration of Getter of bean style property must be prefixed with get. E.g. getName

Declaration of Getter of .net style property must be prefixed with get_ . E.g. get_Name()

Declaration of Setter of .net style property must be prefixed with set. E.g. setName()

Declaration of Setter of .net style property must be prefixed with set_ . E.g. set_Name()

Bean Style readonly boolean property can have one more prefix ‘is’. E.g isInitialized.

No equivalent construct here.

Declaration of Getter & Setter must be applied @beanproperty attribute.

Declaration of Getter & Setter must be applied @property attribute.

The case of the first letter in the property name is converted to lower case unless the property is in all caps, as per the camel casing convention applicable to methods in Java. For Example…

1. getName/setName will be exposed as name out of the assembly.

2. getNaMe/ setNaMe will be exposed as naMe out of the assembly.

3. getNAME/ setNAME will be exposed as NAME out of the assembly.

No change in the casing. Will be shown as it is declared to outside world.

 

 

 

Syntax of a Bean Style Property in J# - How to Declare it

 

Here is the declaration for a bean style property in J#...

 

package JSProperty;

/**

 * Summary description for Point

 */

public class Point

{

private int x;

            /** @beanproperty */

            public int getxValue()

            {

                  return x;

            }

            /** @beanproperty */

            public void setxValue(int value)

            {

                  x = value;

            }

}

 

In the above declaration, you can notice...

  1.  Method name for getter (getxValue) starts with get
  2.  Method name for setter (setxValue ) starts with set
  3.  Both methods have      /** @beanproperty */ attribute applied.
  4.  Method name for setter/getter are same except get and set. This is mandatory if you want to declare a read/write property. If you want to declare a read-only or write-only property then you must not specify setter or getter respectively.

 

Consuming J# declared Bean Properties in C# - No difference from C# declared property - Beauty of .net

 

If I compile above code into an assembly and refer that assembly in a C# project then I will be able to consume the property in C# syntax, as if the property was written in C# syntax, not typical method like syntax of J#. Following is the C# sample consuming above property...

 

using System;

using System.Collections.Generic;

using System.Text;

using JSProperty;

namespace ConsoleApplication1

{

    class TestProgram

    {

         static void Main(string[] args)

   {

        Point p = new Point();

              System.Console.WriteLine("Setting property value to 10");

        p.xValue = 10;

              System.Console.WriteLine("Property has been set to : " +
p.xValue.ToString());

           

    }

    }

}

 

Declaring a read-only or write-only bean style property in J#

 

If you want to declare a read-only or write-only bean style property then you must not specify setter and getter respectively.  So a read-only property will look somewhat like following...

      public class Point

{

private int x;

            /** @beanproperty */

            public int getxValue()

                  {

                        return x;

            }

            // please note that no declaration for setter here

}

 

Similarly if you want to declare a write only property then you should declare only setter,

   

      public class Point

{

private int x;

            /** @beanproperty */

            public void setxValue(int value)

                  {

                        x = value;

            }

           // please note that no declaration for getter here

}

/** @beanproperty */ attribute is critical - Few words of caution

 

In my J# declaration of bean style property if I miss the @beanproperty attribute then J# compiler won't give any error. It will compile fine and will emit the IL for method of the same name. For example if I declare the property as follows...

 

public class Point

{

private int x;

            public int getxValue()

            {

                  return x;

            }

            /** @beanproperty */

            public void setxValue(int value)

            {

                  x = value;

            }

}

 

then J# compiler will generate IL for a method getxValue () and a write-Only property xValue. That means if you refer such an assembly in a C# project then, you will see one method "int getxValue ()" and a write-only property "property int xValue".

 

I have observed many people scratching their head due to similar mistakes. Either they forget to put the /** @beanproperty */ attribute or they spell it wrongly. If you spell the attribute incorrectly then also compiler will not give any error/warning. Reason is that attributes in J# are written inside /** */ construct and you can write java doc comments/comments also inside the same construct. So in case you spell the attribute incorrectly then J# compiler treats that as a comment/doc comment and doesn't give any warning/error.

 

Bean Style Property starting with “is”

To be on par with java beans, J# support writing Boolean bean style read only property starting with “is”. Here is the example giving some insight…

 

public class Point

{

      private int x = - 1;

      private int y;

      public void SetX( int value)

      {

            x = value;

      }

      /** @beanproperty */

      public boolean isValid()

      {

            return x >= 0;

      }

}

In above snippet I have declared boolean style property whose name starts with “is”. I can’t pass any other argument in this property declaration and type must always be boolean. If I don’t follow these two rules then J# compiler gives error.

Here is the C# snippet showing consumption of this bean style property…

class Program

 {

        static void Main(string[] args)

        {

            ConsoleApplication2.Point point = new
ConsoleApplication2.Point();

            bool x = point.valid;

            point.SetX(4);

        x = point.valid;

            int i = 0;

            //int s = point.simpleVaLue;

        }

 }

You can notice here that J# compiler has changed the first letter of property name from uppercase to lower case to confirm the java camel casing.

In the declaration I have declared the name as following…

public boolean isValid()

but in my C# code consuming this property, I am accessing it in lower case…

x = point.valid;

 

Declaring Indexers using Bean Style Properties

 

This is similar to declaring indexers using .net style properties. What all you have to do is…

  1. Apply

/** @attribute System.Reflection.DefaultMember(%propertyname%) */

 

to your class declaration and replace %propertyname% with the bean property you want to convert into indexer.

  1. In the property declaration (getter, setter) add one more argument of int type which will be used as an array index by outside world. Please make sure that this is the very first argument in both getter/setter declaration.

 

Following example will make the things clear…

 

Declaration in J#...

/** @attribute System.Reflection.DefaultMember("VALUE") */

public class Point

{

      private int x;

      private int y;

      /** @beanproperty */

      public int getVALUE(int index)

      {

            switch (index)

            {

                  default:

                  case 0:

                        return x;

                  case 1:

                        return y;

            }

      }

      /** @beanproperty */

      public void setVALUE(int index, int val)

      {

            switch (index)

            {

                  default:

                  case 0:

                        x = val;

                        break;

                  case 1:

                        y = val;

                        break;

            }

      }

}

Consumption in C#...

class Program

    {

      

    static void Main(string[] args)

        {

            ConsoleApplication2.Point point = new
ConsoleApplication2.Point();

            point[0] = 2;

            point[1] = 3;

            int x = point[0];

            int y = point[1];

        }

 }

 

So far so good :).

 

I think this is all about properties in J# from my side. If you have any doubts you may like to

· refer my last posts on properties in J#.

· refer this white paper from our Program Manager Pratap Lakshman.

· Or just post a comment here. I will be more than happy replying on them.

Thanks.

Comments