Results 1 to 15 of 15

Thread: [RESOLVED] Why does C# allow direct access to private members of an object?

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Aug 2020
    Posts
    845

    Resolved [RESOLVED] Why does C# allow direct access to private members of an object?

    I often see code like the following:
    Code:
    internal class MyClass {
        private int _size;
        private int _version;
    
        public Clone(MyClass obj) {
            this._size = obj._size;
            this._version = obj._version;
        }
    }
    Why does C# allow direct access to private members of an object? Closure?
    Last edited by SearchingDataOnly; Jul 4th, 2022 at 09:22 AM.

  2. #2
    Frenzied Member
    Join Date
    Nov 2017
    Posts
    2,038

    Re: Why does C# allow direct access to private members of an object?

    Why does it exist or why does it work?

    If why does it work, then:

    "internal: The type or member can be accessed by any code in the same assembly, but not from another assembly. In other words, internal types or members can be accessed from code that is part of the same compilation."

    Source: https://docs.microsoft.com/en-us/dot...cess-modifiers

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    Aug 2020
    Posts
    845

    Re: Why does C# allow direct access to private members of an object?

    Quote Originally Posted by OptionBase1 View Post
    Why does it exist or why does it work?

    If why does it work, then:

    "internal: The type or member can be accessed by any code in the same assembly, but not from another assembly. In other words, internal types or members can be accessed from code that is part of the same compilation."

    Source: https://docs.microsoft.com/en-us/dot...cess-modifiers
    Access Modifiers (C# Programming Guide):

    private: The type or member can be accessed only by code in the same class or struct

  4. #4
    Frenzied Member
    Join Date
    Nov 2017
    Posts
    2,038

    Re: Why does C# allow direct access to private members of an object?

    Change the class modifier to something other than internal and see if it still works. If not, then it is likely because the class itself is defined as internal.

    Edit to add: I didn't test your sample code to see if that actually works, I'm taking your word for it that does.

  5. #5
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    108,675

    Re: Why does C# allow direct access to private members of an object?

    Quote Originally Posted by SearchingDataOnly View Post
    Access Modifiers (C# Programming Guide):

    private: The type or member can be accessed only by code in the same class or struct
    That code is in the same class or struct, so it's accessible. It doesn't say the same instance of the same class or struct, just the same class or struct.

  6. #6
    Frenzied Member PlausiblyDamp's Avatar
    Join Date
    Dec 2016
    Location
    Newport, UK
    Posts
    1,856

    Re: Why does C# allow direct access to private members of an object?

    Quote Originally Posted by SearchingDataOnly View Post
    I often see code like the following:
    Code:
    internal class MyClass {
        private int _size;
        private int _version;
    
        public Clone(MyClass obj) {
            this._size = obj._size;
            this._version = obj._version;
        }
    }
    Why does C# allow direct access to private members of an object? Closure?
    Isn't that the same with VB6 as well? Private members are private to the class or type, not to the instance.

  7. #7
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    108,675

    Re: Why does C# allow direct access to private members of an object?

    I just noticed that this is a C# question in the VB.NET forum. This site has a C# forum. Don't post in the wrong forum just because you think it will mean getting more people to see your question.

  8. #8
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    7,731

    Re: Why does C# allow direct access to private members of an object?

    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  9. #9
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    108,675

    Re: Why does C# allow direct access to private members of an object?

    Yeah, it makes perfect sense to be able to do this. You can only do it in the same type that the members are declared so, if you're the author of both those private members and the code accessing them, you can make sure they are not accessed in an inappropriate way. Without this feature, cloning and copy constructors would be impossible without exposing data that shouldn't be exposed. It's completely practical.

  10. #10

    Thread Starter
    Fanatic Member
    Join Date
    Aug 2020
    Posts
    845

    Re: Why does C# allow direct access to private members of an object?

    Quote Originally Posted by OptionBase1 View Post
    Change the class modifier to something other than internal and see if it still works. If not, then it is likely because the class itself is defined as internal.

    Edit to add: I didn't test your sample code to see if that actually works, I'm taking your word for it that does.
    Thank you, OptionBase1.

    Quote Originally Posted by jmcilhinney View Post
    That code is in the same class or struct, so it's accessible. It doesn't say the same instance of the same class or struct, just the same class or struct.
    Thank you, jmcilhinney.

    Under normal circumstances, the access rights of the member variables of the class should refer to "the access rights of the member variables of the instance of the class at runtime", not the access rights in the code window. However, since the C# compiler and documentation really have to interpret it in its own way, we can only accept it. In contrast, VB6's approach is more scientific, but inconvenient and inflexible.

  11. #11

    Thread Starter
    Fanatic Member
    Join Date
    Aug 2020
    Posts
    845

    Re: Why does C# allow direct access to private members of an object?

    Quote Originally Posted by PlausiblyDamp View Post
    Isn't that the same with VB6 as well? Private members are private to the class or type, not to the instance.
    In VB6, the access rights of the member variables of the class should refer to "the access rights of the member variables of the instance of the class at runtime", not the access rights in the code window.

    So, in VB6, both Me.m_Size and obj.m_Size are not allowed if m_Size is a private member.
    Last edited by SearchingDataOnly; Jul 5th, 2022 at 09:16 AM.

  12. #12

    Thread Starter
    Fanatic Member
    Join Date
    Aug 2020
    Posts
    845

    Re: Why does C# allow direct access to private members of an object?

    Quote Originally Posted by jmcilhinney View Post
    I just noticed that this is a C# question in the VB.NET forum. This site has a C# forum. Don't post in the wrong forum just because you think it will mean getting more people to see your question.
    I didn't even know there was a C# sub-forum, I thought the C# question was merged into the VB.NET forum.

    Quote Originally Posted by jmcilhinney View Post
    Yeah, it makes perfect sense to be able to do this. You can only do it in the same type that the members are declared so, if you're the author of both those private members and the code accessing them, you can make sure they are not accessed in an inappropriate way. Without this feature, cloning and copy constructors would be impossible without exposing data that shouldn't be exposed. It's completely practical.
    Yes, I agree with that.

    I guess that VB6 uses dynamic compilation in the IDE window to instantly check the code for syntax errors. Therefore, in VB6, the access rights of class member variables can only be in the instance environment. It is also like this, VB6-IDE can do "Edit-Continue" when the code is running. I don't know if VisualStudio.NET can also do "Edit-Continue" while the code is running
    Last edited by SearchingDataOnly; Jul 5th, 2022 at 09:20 AM.

  13. #13
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    CT
    Posts
    18,164

    Re: [RESOLVED] Why does C# allow direct access to private members of an object?

    Quote Originally Posted by SearchingDataOnly View Post
    Closure?
    How I use Closure - this is JS, but concept is the same.

    Simple example:

    Here I am calling a function that will open an EDIT window in the browser.

    It allows you to edit the "report layout" formula for a particular grid that is referenced by that single parameter intGO. That grid sits in a global object (array) of g_objGrid[]. I grab the formula "text", put it in an HTML element, and then call the .DIALOG function to setup the OK and CANCEL buttons. They will run a function that is being created right inline and note that the function can reference intGO. This is Closure - keeping a variable ALIVE even after the editReportLayout function exits, and someone comes along and clicks an OK button.

    Let that sink in.

    I created a function on the fly, that might or might not ever be executed. And it will retain a value that allows access to that g_objGrid array at some later time. And that intGO value is "hidden" from everyone - known only to the function when it might ever execute and bring into scope that very old variable.

    Code:
    function editReportLayout(intGO) {
        $("#acs-formula .acs-dlg-prompt").html("Report Layout Source");
        $("#acs-formula .acs-dlg-label").html("");
        $("#acs-formula .acs-dlg-formula").val(g_objGrid[intGO].awcoptions.reportlayout || "");
        $("#acs-formula").dialog(
                {
                    title: 'Report Layout'
                , buttons: {
                    'Ok': function () {
                        var strLayout = $("#acs-formula .acs-dlg-formula").val();
                        g_objGrid[intGO].awcoptions.reportlayout = strLayout
                        $("#acs-formula").dialog('close');
                    },
                    'Cancel': function () {
                        $("#acs-formula").dialog('close');
                    }
                }
                });
        $("#acs-formula").dialog('open');
    }
    And a more complex example:

    Here I am running a report with printStart - passing in the STORED PROCEDURE to run on the backend server (rptSproc) and some supporting info in ctrlval1, 2 and 3.

    strCT is the "tag" that identifies the HTML element that initiated this report request. The array source optionally contains local web grid "data" to be printed.

    Note that it calls ctrlWebService - that function explained shortly...

    The key item to note in printStart is that it is starting a "timer" to run a "web service" to check the "state" of the report creation. Polling the server to find out how many pages have been printed. And of course the UI needs to know what HTML element to "associate" that returned information with.

    This is accomplished by passing in strCt to that INLINE function being created on the fly. And note that it's also calling ctrlWebService

    Code:
    function printStart(rptSproc, ctrlval1, ctrlval2, ctrlval3, strCT, source) {
        ctrlWebService(rptSproc, ctrlval1, ctrlval2, ctrlval3, strCT, source);
        g_printCycle = 1000;
        setTimeout(function () {
            ctrlWebService("acscheck", "", "", "", strCT, []);
        }, g_printCycle);
    }
    And here is that function - ctrlWebService.

    Basically it's going to create an AJAX call to the server. Nice thing about this type of request is that it's async and allows for "callback" functions to be executed when the browser finally gets the results of the request.

    You can see it does a POST to the web server - runs a web service called CtrlService and most important, upon that AJAX call coming back, runs another function ajaxCtrlFinished.

    That function is being created INLINE, on the fly. Actually three of them for SUCCESS, FAILURE and ERROR.

    And that function created on the fly, needs to know the HTML element - the strId variable here...

    And even more important, a complex OBJECT variable is being held in closure - objWebParam. The cost of this was considered. And more important, it's a locally created object, not something passed in that I have to worry about keeping alive and/or stepping all over with async returns.

    Code:
    function ctrlWebService(strOpt, strVal1, strVal2, strVal3, strId, source, extra) {
        var newId = "";
        var objWebParam = {};
        var wesId = [];
        objWebParam.username = window.username || "";
    .
    .
    .
        var strWebParam = $.toJSON(objWebParam);
        $.ajax({
            type: "POST",
            url: "WebService.asmx/CtrlService",
            dataType: "json",
            data: strWebParam,
            contentType: "application/json; charset=utf-8",
            success: function(msg) {
                ajaxCtrlFinished(msg, strId, "success", objWebParam);
            },
            failure: function(msg) {
                ajaxCtrlFinished(msg, strId, "failure", objWebParam);
            },
            error: function(msg) {
                ajaxCtrlFinished(msg, strId, "error", objWebParam);
            }
        });
    }
    One really cool thing to note is that all these AJAX requests are being processed and will RETURN out of the order that they were sent. I'm polling for "how many pages" many times as a report runs and runs and runs.

    Just for completion sake - here is what that callback function basically looks like

    Code:
    function ajaxCtrlFinished(msg, sender, rtnstatus, objOptions) {
        var objReturn = $.parseJSON(msg.d);
    .
    .
    .
    }
    Last edited by szlamany; Jul 7th, 2022 at 02:32 PM.

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  14. #14

    Thread Starter
    Fanatic Member
    Join Date
    Aug 2020
    Posts
    845

    Re: [RESOLVED] Why does C# allow direct access to private members of an object?

    Very nice and clear code. Thank you, szlamany.

    If 20 years ago, I knew that JavaScript could write such neat and clear code, maybe I started learning and using JavaScript 20 years ago. At that time, all the JavaScript I saw was so messed up as spaghetti that I had no interest in learning and using it at the time, and because of that, I missed out on the best programming language in the world for up to 20 years.

  15. #15
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Posts
    4,048

    Re: Why does C# allow direct access to private members of an object?

    Quote Originally Posted by SearchingDataOnly View Post
    I don't know if VisualStudio.NET can also do "Edit-Continue" while the code is running
    It can. It's a per language feature (not per IDE). Dynamic compilation or not E&C is possible. . . hard but still very much possible to implement.

    The feature does not depend on having private members accessible or not. In VB6 Watched windows you have all private variables *and* constants available on any instance running in the IDE (not from compiled components) i.e. instances from the interpreter heap are fully introspectable.

    cheers,
    </wqw>

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width