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. .NET Framework Cruft

.NET Framework Cruft

Scheduled Pinned Locked Moved The Lounge
csharpdotnetcssalgorithmsregex
13 Posts 4 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.
  • M Offline
    M Offline
    Mike Marynowski
    wrote on last edited by
    #1

    I've been thinking about this a lot, but I have no particularly good solution for it. Sorry, this is going to be a bit "ranty". The .NET Framework has a ton of cruft in it, mostly due to Microsoft's incessant commitment to never breaking backwards compatibility. This adds a lot of unnecessary complexity to the framework and makes the initial learning curve a lot harder and less intuitive than it needs to be. It's not the fact that it is there that bothers me, it's that I have to look at it and deal with it all the time. There should be some kind of mechanism to deprecate stuff and build transformations so that old code still works but I can look at nicely cleaned up new code for new projects going forward. I don't really know what can be done at this point to fix it though. I was thinking that perhaps a new pseudo-language could be created - lets call it C##. It would use the same BCL under the hood, use the same C# compiler, there would just be a C## preprocessor that would do some clever transformations so that it was valid C# prior to running it through the compiler. That would mean that C## libraries would be fully compatible with C# projects (and vice versa), but for new development you could isolate yourself from all the old crap in the language and framework. Some issues I would fix in this "clean break" language (some of this may not be possible without CLR updates as well): - Transform foreach so the iteration variable is inside the loop (important for closures that close over the iteration variable, where this behavior is essentially always desired). - Add keyword "beforefieldinit" or attribute [BeforeFieldInit] that can be added to the static constructor definition to control class init behavior, instead of the asinine way it handles it now based on whether a static constructor is defined or not. There is absolutely no reason this shouldn't be easily and explicitly controllable by the developer. - Remove all non-generic collections and collection interfaces, or at least fix them so they match their generic equivalents, because this is a bloody nonsensical mess (ICollection != ICollection, IList != IList). Expand the list of interfaces if need be so it actually makes sense (ie why do I have to implement a whole wack of unnecessary IList members with throw new NotImplementedException() just to get a read-only indexable type that plays nice as an observable read-only collection?). I believe this last part has at least been partially addressed in .NET 4.5 though. - In order to h

    W L Richard DeemingR 4 Replies Last reply
    0
    • M Mike Marynowski

      I've been thinking about this a lot, but I have no particularly good solution for it. Sorry, this is going to be a bit "ranty". The .NET Framework has a ton of cruft in it, mostly due to Microsoft's incessant commitment to never breaking backwards compatibility. This adds a lot of unnecessary complexity to the framework and makes the initial learning curve a lot harder and less intuitive than it needs to be. It's not the fact that it is there that bothers me, it's that I have to look at it and deal with it all the time. There should be some kind of mechanism to deprecate stuff and build transformations so that old code still works but I can look at nicely cleaned up new code for new projects going forward. I don't really know what can be done at this point to fix it though. I was thinking that perhaps a new pseudo-language could be created - lets call it C##. It would use the same BCL under the hood, use the same C# compiler, there would just be a C## preprocessor that would do some clever transformations so that it was valid C# prior to running it through the compiler. That would mean that C## libraries would be fully compatible with C# projects (and vice versa), but for new development you could isolate yourself from all the old crap in the language and framework. Some issues I would fix in this "clean break" language (some of this may not be possible without CLR updates as well): - Transform foreach so the iteration variable is inside the loop (important for closures that close over the iteration variable, where this behavior is essentially always desired). - Add keyword "beforefieldinit" or attribute [BeforeFieldInit] that can be added to the static constructor definition to control class init behavior, instead of the asinine way it handles it now based on whether a static constructor is defined or not. There is absolutely no reason this shouldn't be easily and explicitly controllable by the developer. - Remove all non-generic collections and collection interfaces, or at least fix them so they match their generic equivalents, because this is a bloody nonsensical mess (ICollection != ICollection, IList != IList). Expand the list of interfaces if need be so it actually makes sense (ie why do I have to implement a whole wack of unnecessary IList members with throw new NotImplementedException() just to get a read-only indexable type that plays nice as an observable read-only collection?). I believe this last part has at least been partially addressed in .NET 4.5 though. - In order to h

      W Offline
      W Offline
      Wayne Gaylard
      wrote on last edited by
      #2

      So, you want to build a new framework to wrap the old framework, which wraps the older framework. Shew! Where will it all end. Maybe we should just go back to assembly, and be done with it.

      When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman

      M 1 Reply Last reply
      0
      • W Wayne Gaylard

        So, you want to build a new framework to wrap the old framework, which wraps the older framework. Shew! Where will it all end. Maybe we should just go back to assembly, and be done with it.

        When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman

        M Offline
        M Offline
        Mike Marynowski
        wrote on last edited by
        #3

        Hey, as I said in my very first sentence, "I have no particularly good solution for it" :) How do you suggest dealing with increasing bloat and cruft in a constantly evolving framework?

        W 1 Reply Last reply
        0
        • M Mike Marynowski

          Hey, as I said in my very first sentence, "I have no particularly good solution for it" :) How do you suggest dealing with increasing bloat and cruft in a constantly evolving framework?

          W Offline
          W Offline
          Wayne Gaylard
          wrote on last edited by
          #4

          I have never really seen it in your light to be perfectly honest. I have been doing .Net development since around 2002, and have just really had to learn the new stuff whenever they upgraded it. I guess if I had to start learning it all now, it would be a different story.

          When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman

          M 1 Reply Last reply
          0
          • W Wayne Gaylard

            I have never really seen it in your light to be perfectly honest. I have been doing .Net development since around 2002, and have just really had to learn the new stuff whenever they upgraded it. I guess if I had to start learning it all now, it would be a different story.

            When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman

            M Offline
            M Offline
            Mike Marynowski
            wrote on last edited by
            #5

            I've been doing .NET development for a similar period of time, and while I don't personally have problems grasping it, the inconsistencies and design issues that can't be fixed now because they would break backwards compatibility are super annoying. I can see how wierd and confusing certain aspects of the framework are to new recruits that I train though. That, and inconsistencies such as the complete mismatch of IList ==> IList and ICollection ==> ICollection just set my OCD off like mad. I tend to be working on rather low level stuff by typical .NET standards though, so this stuff bothers me more (i.e. being able to control the beforeinitflag would remove hacky workaround code in several libraries we have).

            1 Reply Last reply
            0
            • M Mike Marynowski

              I've been thinking about this a lot, but I have no particularly good solution for it. Sorry, this is going to be a bit "ranty". The .NET Framework has a ton of cruft in it, mostly due to Microsoft's incessant commitment to never breaking backwards compatibility. This adds a lot of unnecessary complexity to the framework and makes the initial learning curve a lot harder and less intuitive than it needs to be. It's not the fact that it is there that bothers me, it's that I have to look at it and deal with it all the time. There should be some kind of mechanism to deprecate stuff and build transformations so that old code still works but I can look at nicely cleaned up new code for new projects going forward. I don't really know what can be done at this point to fix it though. I was thinking that perhaps a new pseudo-language could be created - lets call it C##. It would use the same BCL under the hood, use the same C# compiler, there would just be a C## preprocessor that would do some clever transformations so that it was valid C# prior to running it through the compiler. That would mean that C## libraries would be fully compatible with C# projects (and vice versa), but for new development you could isolate yourself from all the old crap in the language and framework. Some issues I would fix in this "clean break" language (some of this may not be possible without CLR updates as well): - Transform foreach so the iteration variable is inside the loop (important for closures that close over the iteration variable, where this behavior is essentially always desired). - Add keyword "beforefieldinit" or attribute [BeforeFieldInit] that can be added to the static constructor definition to control class init behavior, instead of the asinine way it handles it now based on whether a static constructor is defined or not. There is absolutely no reason this shouldn't be easily and explicitly controllable by the developer. - Remove all non-generic collections and collection interfaces, or at least fix them so they match their generic equivalents, because this is a bloody nonsensical mess (ICollection != ICollection, IList != IList). Expand the list of interfaces if need be so it actually makes sense (ie why do I have to implement a whole wack of unnecessary IList members with throw new NotImplementedException() just to get a read-only indexable type that plays nice as an observable read-only collection?). I believe this last part has at least been partially addressed in .NET 4.5 though. - In order to h

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              Mike Marynowski wrote:

              - In order to help facilitate removing non-generic collection types, let covariance and contravariance work on generic type parameters of classes as well as value types (i.e. IEnumerable<int> can be used as IEnumerable<object>).

              How? Conceptually I agree that this makes sense, but I don't see how it could be implemented.

              M 1 Reply Last reply
              0
              • M Mike Marynowski

                I've been thinking about this a lot, but I have no particularly good solution for it. Sorry, this is going to be a bit "ranty". The .NET Framework has a ton of cruft in it, mostly due to Microsoft's incessant commitment to never breaking backwards compatibility. This adds a lot of unnecessary complexity to the framework and makes the initial learning curve a lot harder and less intuitive than it needs to be. It's not the fact that it is there that bothers me, it's that I have to look at it and deal with it all the time. There should be some kind of mechanism to deprecate stuff and build transformations so that old code still works but I can look at nicely cleaned up new code for new projects going forward. I don't really know what can be done at this point to fix it though. I was thinking that perhaps a new pseudo-language could be created - lets call it C##. It would use the same BCL under the hood, use the same C# compiler, there would just be a C## preprocessor that would do some clever transformations so that it was valid C# prior to running it through the compiler. That would mean that C## libraries would be fully compatible with C# projects (and vice versa), but for new development you could isolate yourself from all the old crap in the language and framework. Some issues I would fix in this "clean break" language (some of this may not be possible without CLR updates as well): - Transform foreach so the iteration variable is inside the loop (important for closures that close over the iteration variable, where this behavior is essentially always desired). - Add keyword "beforefieldinit" or attribute [BeforeFieldInit] that can be added to the static constructor definition to control class init behavior, instead of the asinine way it handles it now based on whether a static constructor is defined or not. There is absolutely no reason this shouldn't be easily and explicitly controllable by the developer. - Remove all non-generic collections and collection interfaces, or at least fix them so they match their generic equivalents, because this is a bloody nonsensical mess (ICollection != ICollection, IList != IList). Expand the list of interfaces if need be so it actually makes sense (ie why do I have to implement a whole wack of unnecessary IList members with throw new NotImplementedException() just to get a read-only indexable type that plays nice as an observable read-only collection?). I believe this last part has at least been partially addressed in .NET 4.5 though. - In order to h

                L Offline
                L Offline
                Lost User
                wrote on last edited by
                #7

                Mike Marynowski wrote:

                There should be some kind of mechanism to deprecate stuff and build transformations so that old code still works but I can look at nicely cleaned up new code for new projects going forward.

                The new stuff is hardly signature-compatible. The only alternative is that all your .NET 1.0 apps simply stop working. Or did you expect MS to magically know what you'd pass into that extra parameter? :) Keeping things compatible means keeping things from breaking. It means "reliable". And, as the market proves, that's worth a few bucks.

                Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]

                M 1 Reply Last reply
                0
                • L Lost User

                  Mike Marynowski wrote:

                  - In order to help facilitate removing non-generic collection types, let covariance and contravariance work on generic type parameters of classes as well as value types (i.e. IEnumerable<int> can be used as IEnumerable<object>).

                  How? Conceptually I agree that this makes sense, but I don't see how it could be implemented.

                  M Offline
                  M Offline
                  Mike Marynowski
                  wrote on last edited by
                  #8

                  What do you mean? It already works for reference types, it would just needs some IL tricks or runtime support to allow auto-boxing for value types.

                  L 1 Reply Last reply
                  0
                  • L Lost User

                    Mike Marynowski wrote:

                    There should be some kind of mechanism to deprecate stuff and build transformations so that old code still works but I can look at nicely cleaned up new code for new projects going forward.

                    The new stuff is hardly signature-compatible. The only alternative is that all your .NET 1.0 apps simply stop working. Or did you expect MS to magically know what you'd pass into that extra parameter? :) Keeping things compatible means keeping things from breaking. It means "reliable". And, as the market proves, that's worth a few bucks.

                    Bastard Programmer from Hell :suss: If you can't read my code, try converting it here[^]

                    M Offline
                    M Offline
                    Mike Marynowski
                    wrote on last edited by
                    #9

                    I think you are missing the point and looking at the problem with blinders on. Many languages have successfully implemented better versioning mechanisms that allow for these kinds of changes. The old stuff would still be in there, so there would be no compatibility issues. It would just be hidden from projects that target newer framework versions. Some languages have a tag that you can put at the top of a source file, kind of like an html doctype tag, that indicates language version compatibility level, so you can even mix different versions in a single project. That way, if you want to copy and paste a class from a different project that targeted an earlier version, you can still do that. *EDIT* typo fixed...

                    1 Reply Last reply
                    0
                    • M Mike Marynowski

                      What do you mean? It already works for reference types, it would just needs some IL tricks or runtime support to allow auto-boxing for value types.

                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #10

                      Yes, but that's precisely the problem isn't it, where should auto-boxing happen? There isn't anywhere for the box instruction to go unless you wrap the IEnumerable<int> in a special class that does it - you can't put it at the consumer site because an IEnumerable<object> may be an IEnumerable<class>, and I don't see how you could put it at the producer site at all. So ok, you can do that wrapper, but the compiler needed special magic knowledge of IEnumerable<T> to be able to make that wrapper. What should the wrapper look like if it's some other type? How can it even know?

                      M 1 Reply Last reply
                      0
                      • L Lost User

                        Yes, but that's precisely the problem isn't it, where should auto-boxing happen? There isn't anywhere for the box instruction to go unless you wrap the IEnumerable<int> in a special class that does it - you can't put it at the consumer site because an IEnumerable<object> may be an IEnumerable<class>, and I don't see how you could put it at the producer site at all. So ok, you can do that wrapper, but the compiler needed special magic knowledge of IEnumerable<T> to be able to make that wrapper. What should the wrapper look like if it's some other type? How can it even know?

                        M Offline
                        M Offline
                        Mike Marynowski
                        wrote on last edited by
                        #11

                        It doesn't need special knowledge of IEnumerable, it needs special knowledge of generic type arguments that are value types. Instead of throwing a cast exception, in this special case it can auto-generate an invisible wrapper class that does the boxing, kind of how it auto-generates concrete classes for every different type parameter used in a generic class. It just needs to mirror all the method signatures and cast the value type to object.

                        1 Reply Last reply
                        0
                        • M Mike Marynowski

                          I've been thinking about this a lot, but I have no particularly good solution for it. Sorry, this is going to be a bit "ranty". The .NET Framework has a ton of cruft in it, mostly due to Microsoft's incessant commitment to never breaking backwards compatibility. This adds a lot of unnecessary complexity to the framework and makes the initial learning curve a lot harder and less intuitive than it needs to be. It's not the fact that it is there that bothers me, it's that I have to look at it and deal with it all the time. There should be some kind of mechanism to deprecate stuff and build transformations so that old code still works but I can look at nicely cleaned up new code for new projects going forward. I don't really know what can be done at this point to fix it though. I was thinking that perhaps a new pseudo-language could be created - lets call it C##. It would use the same BCL under the hood, use the same C# compiler, there would just be a C## preprocessor that would do some clever transformations so that it was valid C# prior to running it through the compiler. That would mean that C## libraries would be fully compatible with C# projects (and vice versa), but for new development you could isolate yourself from all the old crap in the language and framework. Some issues I would fix in this "clean break" language (some of this may not be possible without CLR updates as well): - Transform foreach so the iteration variable is inside the loop (important for closures that close over the iteration variable, where this behavior is essentially always desired). - Add keyword "beforefieldinit" or attribute [BeforeFieldInit] that can be added to the static constructor definition to control class init behavior, instead of the asinine way it handles it now based on whether a static constructor is defined or not. There is absolutely no reason this shouldn't be easily and explicitly controllable by the developer. - Remove all non-generic collections and collection interfaces, or at least fix them so they match their generic equivalents, because this is a bloody nonsensical mess (ICollection != ICollection, IList != IList). Expand the list of interfaces if need be so it actually makes sense (ie why do I have to implement a whole wack of unnecessary IList members with throw new NotImplementedException() just to get a read-only indexable type that plays nice as an observable read-only collection?). I believe this last part has at least been partially addressed in .NET 4.5 though. - In order to h

                          Richard DeemingR Offline
                          Richard DeemingR Offline
                          Richard Deeming
                          wrote on last edited by
                          #12

                          Mike Marynowski wrote:

                          - Transform foreach so the iteration variable is inside the loop (important for closures that close over the iteration variable, where this behavior is essentially always desired).

                          Already done in 4.5: http://stackoverflow.com/a/12112959/124386[^]

                          Mike Marynowski wrote:

                          why do I have to implement a whole wack of unnecessary IList members with throw new NotImplementedException() just to get a read-only indexable type that plays nice as an observable read-only collection?

                          IReadOnlyCollection<T>[^], IReadOnlyList<T>[^] and IReadOnlyDictionary<TKey, TValue>[^] were added in 4.5: http://visualstudiomagazine.com/articles/2012/08/07/new-read-only-collection-interfaces-for-net.aspx[^]


                          "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                          "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                          M 1 Reply Last reply
                          0
                          • Richard DeemingR Richard Deeming

                            Mike Marynowski wrote:

                            - Transform foreach so the iteration variable is inside the loop (important for closures that close over the iteration variable, where this behavior is essentially always desired).

                            Already done in 4.5: http://stackoverflow.com/a/12112959/124386[^]

                            Mike Marynowski wrote:

                            why do I have to implement a whole wack of unnecessary IList members with throw new NotImplementedException() just to get a read-only indexable type that plays nice as an observable read-only collection?

                            IReadOnlyCollection<T>[^], IReadOnlyList<T>[^] and IReadOnlyDictionary<TKey, TValue>[^] were added in 4.5: http://visualstudiomagazine.com/articles/2012/08/07/new-read-only-collection-interfaces-for-net.aspx[^]


                            "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                            M Offline
                            M Offline
                            Mike Marynowski
                            wrote on last edited by
                            #13

                            I knew there were some new collection interfaces which is why I said that point was already at least partially taken care of in 4.5, but that's awesome regarding foreach! I'm kind of shocked about that, Jon Skeet had a few blog posts about the topic where he said they can't change it now as it could break existing applications and code. Thanks for sharing!

                            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