Initializing read only properties in a derived class' constructor?

  1. #1

    Initializing read only properties in a derived class' constructor?

    How come the following code can set a read only property "Reader":
    new ext.Store()
                {
    
                    ID = "store",
                    Proxy =
                    {
    
                        new  ext.RestProxy()
                        {
                            Url = "/infohubuser",
                            Reader = {
                                new ext.JsonReader()
                                {
    
                                    RootProperty="data",
                                    //SuccessProperty = "success",
                                    MessageProperty = "message"
                                }
                            },
                            Writer =
                            {
                                new ext.JsonWriter()
                                {
                                    //Encode = true,
                                    //RootProperty="data"
                                    AllowSingle = true
    
                                }
                            },
    
                        }
                    },
    But I can't seem to set it in a derived class constructor as such:
     public class InfoHubUserProxy : AjaxProxy
        {
            public InfoHubUserProxy(): base()
            {
    
                Url = "/infohubuser";
                Reader = ...
            }
    
        }
    And how come the API property of RestProxy is not available to set in the first code block?
    I am hoping to code all of my UI classes through a simple subclassing of the most fitting class but it seems the config property visibilities are not the same there and some properties are not able to be set...

    Thanks
  2. #2
    Ok - it seems intellisense is getting messed up and API is indeed available as a property in RestProxy (inherited from abstract base class ServerProxy), however since it has only a getter, again it is nonassignable. How would I initialize the API and Reader properties that only have getters, inside of the constructor for a derived class from RestProxy?

    Thanks
    Last edited by tolgaerdogus; Feb 06, 2017 at 7:50 PM.
  3. #3
    Hello again!

    Check out these two examples:

    - DataView - Advanced - Multi Sort
    - GridPanel - Update - Restful

    Remember, the examples explorers are your friends (both MVC and WebForms ones). You can grab them from github:
    - WebForms Examples Explorer
    - MVC Examples Explorer

    Hope this helps!
    Fabrício Murta
    Developer & Support Expert
  4. #4
    Fabricio,

    thanks for your continued help - I really appreciate it.

    I guess, put more clearly, what I am looking for is how to get around the compilation problem due to the Reader and API properties having getters only:


    Error CS0200 Property or indexer 'ServerProxy.API' cannot be assigned to -- it is read only AdminToolWeb
    Error CS0200 Property or indexer 'ServerProxy.Reader' cannot be assigned to -- it is read only AdminToolWeb


     public class InfoHubUserProxy : RestProxy
        {
            public InfoHubUserProxy() : base()
            {
                Store s = new Store();
                Model m = new Model();
    
                Url = "/infohubuser";
                Reader = new ReaderCollection
                {
                    new ext.JsonReader()
                    {
    
                        RootProperty = "data",
                        //SuccessProperty = "success",
                        MessageProperty = "message"
                    }
                };
                API = new CRUDUrls()
                {
                    Read = "",
                    Update = "",
                    Create = "",
                    Destroy = ""
                };
            }
    
        }
  5. #5
    There may be sophisticated reasons why these "readonly" properties were declared with only a getter, however I think it would be better to declare them with an auto property getter and private setter, thus derived classes would be able to set the value inside of constructors as per c# 6.0 spec.

    In the absence of that, I have found that the following works since the getters are at least declared with the virtual keyword and are hence overridable:

        public class InfoHubUserProxy : RestProxy
        {
            public override CRUDUrls API { get; }
            public override ReaderCollection Reader { get; }
            public override WriterCollection Writer { get; }
            public InfoHubUserProxy() : base()
            {
                Store s = new Store();
                Model m = new Model();
    
                Url = "/infohubuser";
                Reader = new ReaderCollection
                {
                    new ext.JsonReader()
                    {
    
                        RootProperty = "data",
                        //SuccessProperty = "success",
                        MessageProperty = "message"
                    }
                };
                Writer = new WriterCollection
                            {
                    new ext.JsonWriter()
                    {
                        //Encode = true,
                        //RootProperty="data"
                        AllowSingle = true
    
                    }
            };
                API = new CRUDUrls()
                {
                    Read = "read",
                    Update = "update",
                    Create = "create",
                    Destroy = "destroy"
                };
            }
    
        }
    Please do let me know if I am not supposed to be doing this or there is a better way to accomplish this...

    Thanks
  6. #6
    Hello @tolgaerdogus!

    I think I misunderstood your initial question, and the examples don't really show the main point, which is extending the component.

    But yes, your conclusion is right! These properties are defined with getter only exactly to allow extending it, maybe not exactly as you are extending, but to allow, for example, for you to make a derived class from the Ext.Net.JsonReader and provide it as argument to the main component without having to override the whole component. This was mainly thought of based on experience with components that use a store, to allow users to extend them with ease.

    This have been done way before C# 6 specification were out, and we maintain backwards compatibility with previous C# versions so, we can't just apply them currently -- unless we code them with preprocessor macros.

    Your conclusion looks sane and if it works for you, well, it really does work for us! But I'll give your first question again a thought to see if I can get down to a simpler or just different approach or conclusion you got to.
    Fabrício Murta
    Developer & Support Expert
  7. #7
    Alright, hello again! Let me try to put this in easier words:

    What you need is, make a sub-class that would auto-set the (for example) Reader for your component?

    For example, you have to do this same reader to several other components, so you want just to "bundle" this on a sub class:

    var RestProxy = new RestProxy() {
        Url = "www.ext.net",
        Reader = {
            new JsonReader()
            {
                RootProperty = "mypro",
                MessageProperty = "msgpro"
            }
        }
    };
    So you could do something like this:

    var MyRestProxy = new MyProxy() {
        Url = "www.ext.net"
    };
    And just have it with the same reader of the base RestProxy class?

    For this, you would have to declare your class like that:

    public class MyProxy : RestProxy
    {
        public MyProxy() : base()
        {
            this.Reader.Add(new JsonReader()
            {
                RootProperty = "mypromy",
                MessageProperty = "msgpromy"
            });
        }
    }
    In other words, the collection would already be a thing when the class constructor is called, so you have just to add the reader to the collection.

    public class MyProxy : RestProxy
    {
        public MyProxy() : base()
        {
            this.Reader.Add(new JsonReader()
            {
                RootProperty = "mypromy",
                MessageProperty = "msgpromy"
            });
        }
    }
    This would though result in an error at run-time if your derived class is initialized with the reader provided in the constructor "sugar" like this:

    var MyRestProxy = new MyProxy()
    {
        Url = "www.ext.net",
        Reader = {
            new JsonReader()
            {
                RootProperty = "mypro",
                MessageProperty = "msgpro"
            }
        }
    };
    This is because the way above is the same of:

    var MyrestProxy = new MyProxy();
    MyrestProxy.Url = "www.ext.net";
    MyrestProxy.Reader.Add(new JsonReader()
    {
        RootProperty = "mypro",
        MessageProperty = "msgpro"
    });
    And there's no way to tell the constructor the reader was specified with the constructor using the object initializer syntax.

    I hope now the response is more in the lines of your actual question!
    Fabrício Murta
    Developer & Support Expert

Similar Threads

  1. [CLOSED] Error Initializing Session ?
    By CarWise in forum 2.x Legacy Premium Help
    Replies: 2
    Last Post: Jan 09, 2014, 7:57 AM
  2. [CLOSED] How to change the css class properties dynamically
    By ISI in forum 1.x Legacy Premium Help
    Replies: 2
    Last Post: Aug 04, 2011, 10:26 AM
  3. Replies: 2
    Last Post: May 02, 2011, 9:08 PM
  4. Initializing MultiField Controls in Tabs
    By IFLOW in forum 1.x Help
    Replies: 2
    Last Post: Jul 30, 2010, 10:16 AM
  5. Replies: 4
    Last Post: Jul 15, 2010, 4:25 PM

Posting Permissions