Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. c# Const vs. Readonly, Scope, Usings

c# Const vs. Readonly, Scope, Usings

Scheduled Pinned Locked Moved The Lounge
csharpdatabasevisual-studiobusinessjson
44 Posts 17 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • OriginalGriffO OriginalGriff

    Quote:

    Why can't I say

    const DateTime today = DateTime.Now;

    Because DateTime.Now is not a compile-time constant, it's a run time property which returns an non-constant value. Suppose it did allow it: what value should be in today? The DatetIme when the app was started? When the assembly containing the code was loaded? When the class containing the constant value was statically initialized? What would happen if two different classes (or worse assemblies) both declared the same value? Would they be the same? Should they be? How would the system decide for you? That's the point of const vs readonly - the former is a compile time constant value, the later is a runtime constant value. That way, you have the choice for what exactly you want to do, rather than letting the system try to make up it's mind for you.

    Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!

    T Offline
    T Offline
    TheGreatAndPowerfulOz
    wrote on last edited by
    #12

    OriginalGriff wrote:

    That's the point of const vs readonly - the former is a compile time constant value, the later is a runtime constant value.

    While this is true, readonly is used for objects (except for _string_ :rolleyes:) as a compiler hack because _const_ant (i.e. _readonly_) objects are really pointers whose value varies at load time. The fact the compiler writers did it for string means they could have done it for any object. But, I'm not interested in the object's pointer, I'm interested in the object's _const_ant value.

    #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

    F 1 Reply Last reply
    0
    • D dandy72

      pherschel wrote:

      How about a free keyword on a variable or something to get me out of the business of resource management

      Isn't that a contradiction in terms? Having done over a decade of C++ (and not missing it one bit), it seems to me that if you want a 'free' keyword, then you're not getting out of the business of resource management, you're asking to get into it... I must be completely misunderstanding something.

      T Offline
      T Offline
      TheGreatAndPowerfulOz
      wrote on last edited by
      #13

      dandy72 wrote:

      I must be completely misunderstanding something.

      Or he is...

      #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

      D 1 Reply Last reply
      0
      • OriginalGriffO OriginalGriff

        Quote:

        Why can't I say

        const DateTime today = DateTime.Now;

        Because DateTime.Now is not a compile-time constant, it's a run time property which returns an non-constant value. Suppose it did allow it: what value should be in today? The DatetIme when the app was started? When the assembly containing the code was loaded? When the class containing the constant value was statically initialized? What would happen if two different classes (or worse assemblies) both declared the same value? Would they be the same? Should they be? How would the system decide for you? That's the point of const vs readonly - the former is a compile time constant value, the later is a runtime constant value. That way, you have the choice for what exactly you want to do, rather than letting the system try to make up it's mind for you.

        Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!

        P Offline
        P Offline
        pherschel
        wrote on last edited by
        #14

        I can't do this either :(( const DateTime tick = new DateTime(2001, 1, 1);

        - Pete

        T F 2 Replies Last reply
        0
        • P pherschel

          I can't do this either :(( const DateTime tick = new DateTime(2001, 1, 1);

          - Pete

          T Offline
          T Offline
          TheGreatAndPowerfulOz
          wrote on last edited by
          #15

          Of course, you would use _readonly_ for that. I happen to agree with you that _const_ should be allowed in these cases. The _readonly_ verb is an admitted hack by the compiler writers. After all, _string_ is an object (i.e. non-primitive) and you can use _const_ with it.

          #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

          1 Reply Last reply
          0
          • S Slacker007

            Using statements tell .Net to dispose resources/object instances (auto-magically). You nest your using statements so that once that statement block is done executing is is then released (auto-magically). Each nested statement block frees itself upon completion. Edit: Lot's of stuff on the internet about this. Objects have to implement IDisposable to be used in "using statements". I forgot to mention that these questions should be posted in the Q&A so that people can tell you search Google for the answers. Silly me. :-O

            F Offline
            F Offline
            Foothill
            wrote on last edited by
            #16

            That's not entirely true. Look at streams. One would think this is correct.

            using (var outerStream = new MemoryStream(someData))
            {
            using (var innerStream = new TextReader(outerStream))
            {
            // do something
            }
            }

            However, the proper way is this

            var outerStream = new MemoryStream(someData);
            using (var innerStream = new TextReader(outerStream)
            {
            // do something
            }

            This is because the a stream will dispose of the underlying streams when you call Stream.Dispose(). I had code analysis bark at me all the time until I figured this one out.

            if (Object.DividedByZero == true) { Universe.Implode(); } Meus ratio ex fortis machina. Simplicitatis de formae ac munus. -Foothill, 2016

            S C 2 Replies Last reply
            0
            • F Foothill

              That's not entirely true. Look at streams. One would think this is correct.

              using (var outerStream = new MemoryStream(someData))
              {
              using (var innerStream = new TextReader(outerStream))
              {
              // do something
              }
              }

              However, the proper way is this

              var outerStream = new MemoryStream(someData);
              using (var innerStream = new TextReader(outerStream)
              {
              // do something
              }

              This is because the a stream will dispose of the underlying streams when you call Stream.Dispose(). I had code analysis bark at me all the time until I figured this one out.

              if (Object.DividedByZero == true) { Universe.Implode(); } Meus ratio ex fortis machina. Simplicitatis de formae ac munus. -Foothill, 2016

              S Offline
              S Offline
              Slacker007
              wrote on last edited by
              #17

              I was always under the impression that any IO stuff should be done in the "using" statement. Once the memory stream instance is not needed then it will be disposed, no need to kill it manually. Can you please show be some supporting evidence to support your later example, because I don't know that to be entirely true.

              F 1 Reply Last reply
              0
              • F F ES Sitecore

                pherschel wrote:

                Is it me or do you get confused by this? Why can't I say

                const DateTime today = DateTime.Now;

                Constants aren't variables, they just look like them, they are aids for the compiler, they don't exist at run-time. When you write

                const int x = 5;
                int y = 2;
                int z = y + x;
                bool b = z <= x;

                what gets compiled is this

                int y = 2;
                int z = y + 5;
                bool b = z <= 5;

                The compiler replaces all instances of "x" with the constant value. If you could define x as DateTime.Now then what would be compiled? If it literally replaced "x" with "DateTime.Now" everywhere it appears then you almost certainly would not get the result you desire. If it replaced DateTime.Now with the date of compilation then that wouldn't work either. What you really want is a read-only variable, and that's why we have read only variables and constants. You have to understand what they are and use them appropriately, that's not a failing of .net. This is also why you can't make objects const.

                const Person p = new Person();
                p.FirstName = "John";
                p.Age = 33;
                Console.WriteLine (p); // what will the compiler replace "p" with?

                pherschel wrote:

                For properties, why can't I hide the worker variable for the rest of the class?

                Use the short-hand version

                int PageNbr { get; set; }

                Again it's simply a case of understanding the difference and knowing when and where to use the appropriate solution.

                pherschel wrote:

                For destructors, why can't you give me option to destroy right away?

                Because .net is better at memory management than you are and if you leave .net to do your memory management you'll get code that performs well, if you try and do your own memory management you get code that performs badly. For one it means the code is harder for the compiler to optimise as the compiler likes to move your code around for the best overall result but when you have in-line memory management you lesser the optimiser's abilities. Also memory deallocation is expensive. If you could free your objects immediately you probably would (otherwise why would you want this feature?) and that will result in a not-insignificant performance hit. By leaving this aspect to .net it can clear the memory down at a time better suited, like when your app i

                F Offline
                F Offline
                Foothill
                wrote on last edited by
                #18

                F-ES Sitecore wrote:

                Because .net is better at memory management than you are and if you leave .net to do your memory management you'll get code that performs well, if you try and do your own memory management you get code that performs badly.

                Well, you could jump outside of the CLR and allocate memory directly such as

                unsafe
                {
                [DllImport(@"C:\Windows\System32\kernal32.dll")
                public static extern void * HeapAlloc(void * procHeap, UInt32 dword, UInt32 size);
                }

                Not saying that this is a good thing but it's possible and pretty much defeats the purpose of the CLR and GC. Not to mention memory management is one of the most challenging aspects of computer programing. If it weren't for .Net, my programs would most likely leak memory all over the place (my C and C++ KungFu is not strong).

                if (Object.DividedByZero == true) { Universe.Implode(); } Meus ratio ex fortis machina. Simplicitatis de formae ac munus. -Foothill, 2016

                1 Reply Last reply
                0
                • S Slacker007

                  I was always under the impression that any IO stuff should be done in the "using" statement. Once the memory stream instance is not needed then it will be disposed, no need to kill it manually. Can you please show be some supporting evidence to support your later example, because I don't know that to be entirely true.

                  F Offline
                  F Offline
                  Foothill
                  wrote on last edited by
                  #19

                  That little path of discovery started when I started learning the Cryptography namespace. This little code snippet (copied directly from MSDN) was getting flagged with CA2202 during code analysis.

                  // Create the streams used for decryption.
                  using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                  {
                  using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                  {
                  using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                  {
                  // Read the decrypted bytes from the decrypting stream
                  // and place them in a string.
                  plaintext = srDecrypt.ReadToEnd();
                  }
                  }
                  }

                  This really boggled me as this is Microsoft example code being flagged as incorrect so I began to dig. Turns out there is still a lively debate about this since the documentation is a little unclear in this area. Refactoring it to the following stopped the code analysis from flagging the code.

                  MemoryStream memStream = new MemoryStream(data);
                  CryptoStream decStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read);

                  using (StreamReader reader = new StreamReader(decStream))
                  {
                  decryptedValue = Encoding.UTF8.GetBytes(reader.ReadToEnd());
                  }

                  Research into this led me to this one little line in this MSDN article: StreamReader Constructor. The StreamReader object calls Dispose() on the provided Stream object when StreamReader.Dispose is called. This reads that when you close certain classes of streams, they also close the streams that underlie them as well. TL;DR Not all IDisposable classes behave the same way, event in Microsoft code, and the using statement isn't always the correct way.

                  if (Object.DividedByZero == true) { Universe.Implode(); } Meus ratio ex fortis machina. Simplicitatis de formae ac munus. -Foothill, 2016

                  S 1 Reply Last reply
                  0
                  • F Foothill

                    That little path of discovery started when I started learning the Cryptography namespace. This little code snippet (copied directly from MSDN) was getting flagged with CA2202 during code analysis.

                    // Create the streams used for decryption.
                    using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                    {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {
                    // Read the decrypted bytes from the decrypting stream
                    // and place them in a string.
                    plaintext = srDecrypt.ReadToEnd();
                    }
                    }
                    }

                    This really boggled me as this is Microsoft example code being flagged as incorrect so I began to dig. Turns out there is still a lively debate about this since the documentation is a little unclear in this area. Refactoring it to the following stopped the code analysis from flagging the code.

                    MemoryStream memStream = new MemoryStream(data);
                    CryptoStream decStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read);

                    using (StreamReader reader = new StreamReader(decStream))
                    {
                    decryptedValue = Encoding.UTF8.GetBytes(reader.ReadToEnd());
                    }

                    Research into this led me to this one little line in this MSDN article: StreamReader Constructor. The StreamReader object calls Dispose() on the provided Stream object when StreamReader.Dispose is called. This reads that when you close certain classes of streams, they also close the streams that underlie them as well. TL;DR Not all IDisposable classes behave the same way, event in Microsoft code, and the using statement isn't always the correct way.

                    if (Object.DividedByZero == true) { Universe.Implode(); } Meus ratio ex fortis machina. Simplicitatis de formae ac munus. -Foothill, 2016

                    S Offline
                    S Offline
                    Slacker007
                    wrote on last edited by
                    #20

                    Good to know. Thanks.

                    1 Reply Last reply
                    0
                    • T TheGreatAndPowerfulOz

                      OriginalGriff wrote:

                      That's the point of const vs readonly - the former is a compile time constant value, the later is a runtime constant value.

                      While this is true, readonly is used for objects (except for _string_ :rolleyes:) as a compiler hack because _const_ant (i.e. _readonly_) objects are really pointers whose value varies at load time. The fact the compiler writers did it for string means they could have done it for any object. But, I'm not interested in the object's pointer, I'm interested in the object's _const_ant value.

                      #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

                      F Offline
                      F Offline
                      Fabio Franco
                      wrote on last edited by
                      #21

                      TheGreatAndPowerfulOz wrote:

                      The fact the compiler writers did it for string means they could have done it for any object.

                      That's not true, although string is an object, it's a special type of object. It's immutable and can be allocated both on the heap and the stack. Other object types are allocated on the heap exclusively but are not nativelly immutable. Strings also have a mechanism called interning. By default const strings are interned for optimization purposes. Having that said, string gets all kinds of special treatment. Remember that you can only declare a const string literal. For example:

                      const string _myString = String.Empty; //Compile-time error.

                      This also defeats the statement that other reference types could have the same treatment. As every reference type you want to use const with, would have to have a literal representation, so its value could be determined at compile-time. Like the string literal.

                      TheGreatAndPowerfulOz wrote:

                      readonly is used for objects (except for _string_ :rolleyes: )

                      Value types can also be readonly. Reinforcing what Original Griff said, the difference between readonly and const are as simple as one is a run-time constant and the other a compile-time constant. If a variable's value cannot be determined at compile-time, it cannot be a const.

                      To alcohol! The cause of, and solution to, all of life's problems - Homer Simpson ---- Our heads are round so our thoughts can change direction - Francis Picabia

                      T 1 Reply Last reply
                      0
                      • F F ES Sitecore

                        pherschel wrote:

                        Is it me or do you get confused by this? Why can't I say

                        const DateTime today = DateTime.Now;

                        Constants aren't variables, they just look like them, they are aids for the compiler, they don't exist at run-time. When you write

                        const int x = 5;
                        int y = 2;
                        int z = y + x;
                        bool b = z <= x;

                        what gets compiled is this

                        int y = 2;
                        int z = y + 5;
                        bool b = z <= 5;

                        The compiler replaces all instances of "x" with the constant value. If you could define x as DateTime.Now then what would be compiled? If it literally replaced "x" with "DateTime.Now" everywhere it appears then you almost certainly would not get the result you desire. If it replaced DateTime.Now with the date of compilation then that wouldn't work either. What you really want is a read-only variable, and that's why we have read only variables and constants. You have to understand what they are and use them appropriately, that's not a failing of .net. This is also why you can't make objects const.

                        const Person p = new Person();
                        p.FirstName = "John";
                        p.Age = 33;
                        Console.WriteLine (p); // what will the compiler replace "p" with?

                        pherschel wrote:

                        For properties, why can't I hide the worker variable for the rest of the class?

                        Use the short-hand version

                        int PageNbr { get; set; }

                        Again it's simply a case of understanding the difference and knowing when and where to use the appropriate solution.

                        pherschel wrote:

                        For destructors, why can't you give me option to destroy right away?

                        Because .net is better at memory management than you are and if you leave .net to do your memory management you'll get code that performs well, if you try and do your own memory management you get code that performs badly. For one it means the code is harder for the compiler to optimise as the compiler likes to move your code around for the best overall result but when you have in-line memory management you lesser the optimiser's abilities. Also memory deallocation is expensive. If you could free your objects immediately you probably would (otherwise why would you want this feature?) and that will result in a not-insignificant performance hit. By leaving this aspect to .net it can clear the memory down at a time better suited, like when your app i

                        K Offline
                        K Offline
                        kalberts
                        wrote on last edited by
                        #22

                        If you need to explain const to someone with a C background: Think of it as a #define. It is integrated in the the language, processed by the compiler rather than a preprocessor, e.g. it is typed, so it isn't a perfect parallell. Yet, lots of the things people think that should be allowed with const can be answered by "Can you do what you want with C #define statements?" "Constants ain't. Variables won't." - this is what the requests usually boil down to - constants that ain't. (But I can understand that you might be confused by "read-only variables": Considering the semantics, that sounds like an oxymoron, a variable that won't. A more desciptive term would be "set_once", but readonly is firmly established, and can't be changed today. (In C, you could do it by a #define. I used to do that, e.g. #define ever (;;), so that I could write "for ever { ... }", but some of my colleauges insisted that "while (1) {...}" was far more readable. I suggeste that we declared "#define WW3 0" so that we could write "while (!WW3)", but that was met with even stronger protests.)

                        1 Reply Last reply
                        0
                        • P pherschel

                          I can't do this either :(( const DateTime tick = new DateTime(2001, 1, 1);

                          - Pete

                          F Offline
                          F Offline
                          Fabio Franco
                          wrote on last edited by
                          #23

                          That's because const value must be known at compile-time. Instantiating DateTime requires code execution, which will only be done at run-time. For that scenario you have the readonly, a run-time constant (intialized once and never changes). You can only use const on variables that can be represented by literals.

                          To alcohol! The cause of, and solution to, all of life's problems - Homer Simpson ---- Our heads are round so our thoughts can change direction - Francis Picabia

                          1 Reply Last reply
                          0
                          • D dandy72

                            pherschel wrote:

                            How about a free keyword on a variable or something to get me out of the business of resource management

                            Isn't that a contradiction in terms? Having done over a decade of C++ (and not missing it one bit), it seems to me that if you want a 'free' keyword, then you're not getting out of the business of resource management, you're asking to get into it... I must be completely misunderstanding something.

                            K Offline
                            K Offline
                            kalberts
                            wrote on last edited by
                            #24

                            In my historical archives I have preserved a long NetNews-discussion from the late 1990s: Even that late, there were some people insisting that high level languages are just a short-lived fad; programmers will soonrealize that for high-performing programs, you must code in assembler. Fortunately, they were not right. For another fifteen years, I was similarly convinced that to control memory use, you simply had to do mallocs and frees yourself in longhand. No way can an automatic garbage collector know what is the best strategy. Then I read the memory management chapter of "CLR via C#". Again and again, I said to myself: Gee, that's smart! I would never have thought of that! ... So my sceptisism towards garbage collectors dwindled away in a few days. I have several colleagues who have not yet read the same book, so they are still as sceptical as I used to be. Besides, some of them are coding in C rather than C#. If/when you switch from C to C#, you might want to bring some old habits over to the new environment, such as trying to "help" the GC. You should not. Its usefulness is at the same level as telling the C compiler how to use its registers. (I recently read that 'register' will disappear from C++17 - I'd say that is extremely overdue.)

                            D 1 Reply Last reply
                            0
                            • K kalberts

                              In my historical archives I have preserved a long NetNews-discussion from the late 1990s: Even that late, there were some people insisting that high level languages are just a short-lived fad; programmers will soonrealize that for high-performing programs, you must code in assembler. Fortunately, they were not right. For another fifteen years, I was similarly convinced that to control memory use, you simply had to do mallocs and frees yourself in longhand. No way can an automatic garbage collector know what is the best strategy. Then I read the memory management chapter of "CLR via C#". Again and again, I said to myself: Gee, that's smart! I would never have thought of that! ... So my sceptisism towards garbage collectors dwindled away in a few days. I have several colleagues who have not yet read the same book, so they are still as sceptical as I used to be. Besides, some of them are coding in C rather than C#. If/when you switch from C to C#, you might want to bring some old habits over to the new environment, such as trying to "help" the GC. You should not. Its usefulness is at the same level as telling the C compiler how to use its registers. (I recently read that 'register' will disappear from C++17 - I'd say that is extremely overdue.)

                              D Offline
                              D Offline
                              dandy72
                              wrote on last edited by
                              #25

                              Member 7989122 wrote:

                              If/when you switch from C to C#, you might want to bring some old habits over to the new environment, such as trying to "help" the GC. You should not.

                              Well said. When I transitioned from C++ to C#, I read a small amount of material on garbage collection (admittedly, a very small amount), but everything I read convinced me from the get-go that it was pointless to try to do just that, and instead just let it do its job. I've never looked back.

                              1 Reply Last reply
                              0
                              • T TheGreatAndPowerfulOz

                                dandy72 wrote:

                                I must be completely misunderstanding something.

                                Or he is...

                                #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

                                D Offline
                                D Offline
                                dandy72
                                wrote on last edited by
                                #26

                                :laugh: I always give the other guy the benefit of the doubt. Then if it turns out I'm right, I point and laugh.

                                1 Reply Last reply
                                0
                                • F Fabio Franco

                                  TheGreatAndPowerfulOz wrote:

                                  The fact the compiler writers did it for string means they could have done it for any object.

                                  That's not true, although string is an object, it's a special type of object. It's immutable and can be allocated both on the heap and the stack. Other object types are allocated on the heap exclusively but are not nativelly immutable. Strings also have a mechanism called interning. By default const strings are interned for optimization purposes. Having that said, string gets all kinds of special treatment. Remember that you can only declare a const string literal. For example:

                                  const string _myString = String.Empty; //Compile-time error.

                                  This also defeats the statement that other reference types could have the same treatment. As every reference type you want to use const with, would have to have a literal representation, so its value could be determined at compile-time. Like the string literal.

                                  TheGreatAndPowerfulOz wrote:

                                  readonly is used for objects (except for _string_ :rolleyes: )

                                  Value types can also be readonly. Reinforcing what Original Griff said, the difference between readonly and const are as simple as one is a run-time constant and the other a compile-time constant. If a variable's value cannot be determined at compile-time, it cannot be a const.

                                  To alcohol! The cause of, and solution to, all of life's problems - Homer Simpson ---- Our heads are round so our thoughts can change direction - Francis Picabia

                                  T Offline
                                  T Offline
                                  TheGreatAndPowerfulOz
                                  wrote on last edited by
                                  #27

                                  What you say may be true, but _const_ could have and should have been used for both situations.

                                  #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

                                  F 1 Reply Last reply
                                  0
                                  • T TheGreatAndPowerfulOz

                                    What you say may be true, but _const_ could have and should have been used for both situations.

                                    #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

                                    F Offline
                                    F Offline
                                    Fabio Franco
                                    wrote on last edited by
                                    #28

                                    TheGreatAndPowerfulOz wrote:

                                    could

                                    Yes, could, but should it? They behave differently and actually generate different IL code. The compiler could also determine that automatically, when generating IL code. But I don't think that's a good idea, but we will end up in another filosophical discussion. In my opinion this compiler behavior could generate those situations developers don't understand what's happening and why their code does not work as expected.

                                    To alcohol! The cause of, and solution to, all of life's problems - Homer Simpson ---- Our heads are round so our thoughts can change direction - Francis Picabia

                                    T U 2 Replies Last reply
                                    0
                                    • P pherschel

                                      With C# getting to version 7+ I wish I could have some basic improvments. Is it me or do you get confused by this? Why can't I say

                                      const DateTime today = DateTime.Now;

                                      I can see readonly for parameters and such, but I would be happy using const there too

                                      void Doit(const MyObj arg) ...

                                      For properties, why can't I hide the worker variable for the rest of the class?

                                      public int PageNbr
                                      {
                                      int _worker = 9;

                                      get { return _worker;}
                                      set { _worker = value; }
                                      }

                                      For destructors, why can't you give me option to destroy right away? I hate disposing with all its using code bloat. How about a free keyword on a variable or something to get me out of the business of resource management. If you open a file and a DB you have to nest usings before you even get started doing some work! Or maybe I'm missing something?

                                      - Pete

                                      I Offline
                                      I Offline
                                      irneb
                                      wrote on last edited by
                                      #29

                                      What's so wrong with it? If you don't like the idea, you could always just:

                                      var someObject = new MyDisposableObject();
                                      // Do some work with it
                                      someObject.Dispose();

                                      The trouble with that is, if the code never reaches that Dispose line, it won't get called. In which case you then incorporate it into a try-finally block like so:

                                      var someObject = new MyDisposableObject();
                                      try {
                                      // Do some work with it
                                      }
                                      finally {
                                      someObject.Dispose();
                                      }

                                      But ... that's exactly what a using clause does for you ... just a whole lot less coding on your side:

                                      using (var someObject = new MyDisposableObject()) {
                                      // Do some work with it
                                      }

                                      I might have liked an idea where you could add numerous unrelated disposables into the using clause - this may alleviate nesting usings. Though take note that with nesting you've got some control over the order in which they're disposed. Also some disposables are contained in other disposables, and in most such cases disposing the container does so to its contents as well, meaning you only need dispose the final container --> only one using clause. More of an issue for me is the fact that a destructor isn't called deterministically, if at all. If such were possible, then the dispose pattern could be moved into the destructor instead of a dispose method. And even if you forget to dispose it, it would finally happen once the GC frees it from resources. Though this means the entire GC idea needs a revamp, in fact some of C#'s creators also think this is one of the biggest mistakes in the entire DotNet, just that they do know the reasons such choice was made.

                                      1 Reply Last reply
                                      0
                                      • P pherschel

                                        With C# getting to version 7+ I wish I could have some basic improvments. Is it me or do you get confused by this? Why can't I say

                                        const DateTime today = DateTime.Now;

                                        I can see readonly for parameters and such, but I would be happy using const there too

                                        void Doit(const MyObj arg) ...

                                        For properties, why can't I hide the worker variable for the rest of the class?

                                        public int PageNbr
                                        {
                                        int _worker = 9;

                                        get { return _worker;}
                                        set { _worker = value; }
                                        }

                                        For destructors, why can't you give me option to destroy right away? I hate disposing with all its using code bloat. How about a free keyword on a variable or something to get me out of the business of resource management. If you open a file and a DB you have to nest usings before you even get started doing some work! Or maybe I'm missing something?

                                        - Pete

                                        I Offline
                                        I Offline
                                        irneb
                                        wrote on last edited by
                                        #30

                                        From your example (i.e. placing DateTime.Now into a const) ... are you intending to save the compile timestamp into the executable code? What would be the intent? It would be pretty close (if not exactly the same) as the file date of the EXE/DLL. Only idea I could think for this to be used is to check if the executing file has been altered since it was compiled. Though for that I'd rather use some hash value instead, even just CRC would be more comprehensive than a timestamp. To me, the readonly idea makes more sense - i.e. it would save the time the program was started. This is the true difference between const and readonly: Const is as if the compiler changes your code to as if you typed in a literal value. Readonly is a way to make sure a variable only gets assigned its value once - from any calculation at runtime. The two ideas are not interchangeable, at least not in most cases.

                                        1 Reply Last reply
                                        0
                                        • F Fabio Franco

                                          TheGreatAndPowerfulOz wrote:

                                          could

                                          Yes, could, but should it? They behave differently and actually generate different IL code. The compiler could also determine that automatically, when generating IL code. But I don't think that's a good idea, but we will end up in another filosophical discussion. In my opinion this compiler behavior could generate those situations developers don't understand what's happening and why their code does not work as expected.

                                          To alcohol! The cause of, and solution to, all of life's problems - Homer Simpson ---- Our heads are round so our thoughts can change direction - Francis Picabia

                                          T Offline
                                          T Offline
                                          TheGreatAndPowerfulOz
                                          wrote on last edited by
                                          #31

                                          Fabio Franco wrote:

                                          should it?

                                          Yes.

                                          Fabio Franco wrote:

                                          my opinion

                                          Doubt it.

                                          Fabio Franco wrote:

                                          another filosophical discussion

                                          That's what life is about.

                                          #SupportHeForShe Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups