Compiler Error CS0542 : member names cannot be the same as their enclosing type



  • What in this code could possibly trigger a compiler error complaining of

    "member names cannot be the same as their enclosing type"

    <FONT face="Courier New">class Item
    {
       public int this[int i]
       {
          get
          {
             return 0;
          }
       }
    }</FONT>

    This turned up during daily coding and we were stumped until we checked the MSDN page for this error code.

    Seems to me this is what happens when syntactic sugar turns bad.....



  • Haha! Oh dear, that is a WTF for sure, though it took me a little while to get it.

    For non-C#y people, the this[arg] syntax allows you to 'index' the class (myItem[3]). It's a tasty piece of syntactic sugar and it sweetens built-in classes like ArrayList, Hashtable and so forth. The problem here is that indexers, while nameless in C#, are compiled to be called 'Item' in the CLR ... so it clashes with the class name.

    A subsidiary WTF is why, since the name Item isn't visible from the language, why they didn't pick something a bit less likely to be a class name, _item or something. (I know it can't be completely unreadable as other .Net languages may need to use it.)



  • @orgchart said:

    What in this code could possibly trigger a compiler error complaining of

    "member names cannot be the same as their enclosing type"

    <font face="Courier New">class Item
    {
       public int this[int i]
       {
          get
          {
             return 0;
          }
       }
    }</font>

    This turned up during daily coding and we were stumped until we checked the MSDN page for this error code.

    Seems to me this is what happens when syntactic sugar turns bad.....



    That's what happens when people don't understand the language that they are using.  If you want to use Indexers, you should understand how they work and what they generate.


  • What a belittling statement. Do you expect a C# programmer to know the machine code generated by the JIT compilation of their MSIL program too? No, because it's not something a high-level language programmer should need to concern themselves with. Them's the benefits of abstractions.

    It's not the language itself that's the issue; it's the way Microsoft chose to implement the language on the underlying platform.

    These implementation details are intended to be hidden (unless explicitly required by the user), and IMO side-effects like this indicate a failure in the abstraction's implementation.



  • @Swig said:

    What a belittling statement. Do you expect a C# programmer to know the machine code generated by the JIT compilation of their MSIL program too? No, because it's not something a high-level language programmer should need to concern themselves with. Them's the benefits of abstractions.

    It's not the language itself that's the issue; it's the way Microsoft chose to implement the language on the underlying platform.

    These implementation details are intended to be hidden (unless explicitly required by the user), and IMO side-effects like this indicate a failure in the abstraction's implementation.



    Actually,  you're right:  it is not well documented that a property called "Item" is created when you create an indexer, they should have made that more clear.  So I see your point.  


  • It's called The Law of Leaky Abstractions.  Just another corner case that somebody ran into.



  • @Swig said:

    What a belittling statement. Do you expect a C# programmer to know the machine code generated by the JIT compilation of their MSIL program too? No, because it's not something a high-level language programmer should need to concern themselves with. Them's the benefits of abstractions.

    That's an erroneous opinion that will lead to bugs. There's no such thing as Object-Oriented programming or abstraction. Those are human concepts designed to make code maintenance easier. From the computer's perspective, it's all binary. (Even HEX is an abstraction!) You should know what sort of code you're making. You aren't making C# code, you're telling the compiler what machine code to produce. Anybody who has ever told you a different story is wrong. It certainly looks like C# code, but it's not. They are instructions to the compiler, which will automatically generate machine code for you. If you don't understand your audience - the computer - then you're just banging away on the keyboard.

    In other words, I expect anyone who considers themselves to be a professional programmer or a Software Engineer to know what they're doing. What you're doing is making machine code. If you don't understand that and keep that in mind at all times, then you're either a Pantless Prima Donna or incompetent.

    Yes, MS chose an exceptionally poor default name (something like _MSInternalAbstractionDefaultName would be more suitable) and the error produced is stupid. It's impossible to make a class called "item", which is exceedingly peculiar, to say the least.



  • @themagni said:

    If you don't understand your audience - the computer - then you're just banging away on the keyboard.

    In other words, I expect anyone who considers themselves to be a professional programmer or a Software Engineer to know what they're doing. What you're doing is making machine code. If you don't understand that and keep that in mind at all times, then you're either a Pantless Prima Donna or incompetent.



    This approach is IMO fundamentally wrong. In many cases, you write programs in a high-level language but you cannot know how the computer will interpret it below the level of abstraction defined by the programming language, because you do not even know the target platform yet. You just have to rely on the compiler, interpreter, runtime, whatever to behave as specified.
    For example, some of my programs, written in C, are used on Unix machines with a Risc processor as well as on Windows Machines with an Intel processor. I have no idea which machine code the compilers will generate and I don't want to know. But of course I have to make sure that my program does not contain constructs with undefined behaviour, like the "i=i++;" example recently discussed here.



  • @themagni said:

    Yes, MS chose an exceptionally poor default name (something like _MSInternalAbstractionDefaultName would be more suitable) and the error produced is stupid.



    Har har, where is the code review for the checkins during the last 10 months?



  • @themagni said:

    That's an erroneous opinion that will lead to bugs. There's no such thing as Object-Oriented programming or abstraction.
    Those are human concepts designed to make code maintenance easier. From
    the computer's perspective, it's all binary.



    Hell, binary is an abstraction.  Lets all think in terms of electrical impulses!

    ammoq above has it right, but I'd just like to add one thing.

    Complex software is complex.  If you start to worry about details below your level of abstraction you'll write inferior software because you spend too much time dealing with stuff you shouldn't be.  While developing, know your environment and assume it works as documented.  While testing, make sure it actually does work that way.



  • MS created a time bomb when they used "Item" as a temp compiler-generated name. Why not A name like [b]GLEOPX[/b] or [b]ur8y563ffu38yjvhg[/b]? The computer don't care. :)

    But let it be said that orgchart violated the semantic principle by calling his class "Item".

    It's like a DIV with id "the_div" or "block"
    A CSS classname ".green" or ".big"
    arrArray[];
    var x;
    4.gif [i](true story! lazy slicing from photoshop)[/i]
    header2()

    Hard to edit.
    I mean, picture yourself writing some code on Friday, and the next Monday, after a beerful weekend:
    [i]fuck.. what was x for again?[/i]


    I do admit, however, that I myself can sometimes get a bit verbose in my naming. Once, I used four underscores in an id. At a certain point, the law of diminishing returns kicks in. :)

    My orignal JS element selector alias for getElementById was Thing('id').


    Complex software is complex.  If you start to worry about details below
    your level of abstraction you'll write inferior software because you
    spend too much time dealing with stuff you shouldn't be.  While
    developing, know your environment and assume it works as documented. 
    While testing, make sure it actually does work that way.


    Exactly.

    Formula-1 drivers have mechanics to worry about their car, so the drivers can focus on the handling the car, as an abstracted unit, and making the best lap time.



  • @dhromed said:


    Complex software is complex.  If you start to worry about details below
    your level of abstraction you'll write inferior software because you
    spend too much time dealing with stuff you shouldn't be.  While
    developing, know your environment and assume it works as documented. 
    While testing, make sure it actually does work that way.


    Exactly.

    Formula-1 drivers have mechanics to worry about their car, so the drivers can focus on the handling the car, as an abstracted unit, and making the best lap time.

    All F1 drivers, past and present, are excellent mechanics.  They have to be, in order to understand why their car is behaving the way it is.  Yes, the mechanics are there to solve the really tough problems, and to do all the hands on work.  But if the driver can't articulate what is happening to their car, then the mechanics can't do much.  They must have a complete understanding of their car in order to drive it to it's limit.

    I interviewed a developer for a position at our company, and we talked about how C++ implements virtual functions.  He argued that a developer shouldn't need to understand those kind of things.  I argued that you do if you ever run into a problem with virtual functions, how are you going to fix it if you don't understand how it is implemented by the compiler?  Can you add a function to a struct{} without affecting the size or memory layout of the struct{}?  What about virtual functions?  At some point, the whole higher level abstraction breaks down, and you need to understand what is really going on.



  • @mhughes said:

    Hell, binary is an abstraction.  Lets all think in terms of electrical impulses!



    Well, yes, you have to do that, too. If the underlying hardware fails, you can't possibly expect your software to run correctly. ;)

    You don't have to program in binary or impulses. That's what the abstraction layers are for. They aren't for allowing you to forget that you're writing instructions to the compiler that will produce machine code. When the abstraction breaks down, then you're boned. The END USER is the one that gets to ignore the abstraction and just know "how to use the thingy". If you're not at least aware of the fact that your code never executes in the form that you see it, then all you're doing is "using the thingy".

    Sometimes, very rarely, you may have to code in assembly and make sure the code is fast enough. Or you'll want to check the ASM files. (If your compiler generates those.) A lot of DSP code is done in assembly just to make sure it's fast enough.

    On even rarer occasions, you might have to go even more primitive. I once had to go directly into HEX and modify programs because the compiler just wouldn't do a good enough job. (Yes, in real life, after graduation, for money.) The tweak saved my old company about 4 weeks of work every month.



  • @Grimoire said:

      Can you add a function to a struct{} without affecting the size or memory layout of the struct{}?  What about virtual functions?  At some point, the whole higher level abstraction breaks down, and you need to understand what is really going on.


    Yes, you need to understand how things are layed out in memory, for C++, at least.

    However, you do NOT need to know the exact sequence of machine language instructions the compiler is generating!

    Can YOU tell me the exact sequence of machine language instuctions that are generated by a given block of C++?  Of course not!

    And as mentioned above: in many languages, e.g. Java, you can't possibly know, because not only do you not know what platform your code is running on, you don't even know which VM its running in!  HotSpot and the Sun VM will generate different instructions!



  • @Grimoire said:


    All F1 drivers, past and present, are excellent mechanics.  They have to be, in order to understand why their car is behaving the way it is.


    And yes, F1 drivers may very well be mechanics.  But they're less than
    1% of drivers!  Not all programmers are F1 drivers, nor do they need to
    be!  Most applications are incredibly mundane, and are just fine sitting several levels of abstraction above the hardware.

    If you're writing a PHP ecommerce site, you don't need to know wether your system stores integers in big endian or little endian.  You don't even need to know the instruction set of the processor your system will be running on.


  • ♿ (Parody)

    @dhromed said:

    MS created a time bomb when they used "Item" as a temp compiler-generated name. Why not A name like [b]GLEOPX[/b] or [b]ur8y563ffu38yjvhg[/b]? The computer don't care. :)

    There's a very good reason for this. Let's consider a C# indexer:

    public MyClass this[int index];

    When this is compiled, this is turned into the following MSIL (give or take)

    .method specialname instance class MyClass get_Item(int index);
    .method specialname instance class void set_Item(int index, MyClass value);

    This shows is that a "C# Indexer" is simply of type MyClass, has a parameter, and the specialname attribute. What if your host language (let's say, VB.NET) doesn't support C#-style indexers? That means that consumers (not just computers) will have to SEE the name of property. This wouldn't make much sense:

    Public Default Property ur8y563ffu38yjvhg(index As Integer) As MyClass

    The C# team (careful distinction from Microsoft, since the C# team is a group of highly-specialized, incredibly smart experts) decided to permit Indexers only in this manner, probably to ensure that properties aren't abused and used as methods.

    So, clearly, this isn't a "WTF" at all. We do, hower, have "The Real WTF" in this following statement:

    @Swig said:

    Do you expect a C# programmer to know the machine code generated by the JIT compilation of their MSIL program too? No, because it's not something a high-level language programmer should need to concern themselves with.

    That's a disturbing statement demonstrating a willful ignorance of the tool you are using. How can you expect to be a sucessful programmer if you refuse to take the time to attain a high-level understanding of what your code is doing?  This is CLR basics here, not complex MSIL stuff.

    The "WTF" you brought up is the mistake I'd expect from a Developer I. Compound that with the name of the class ("Item"), your inability to rectify the error with a few minutes of research and the CompilerServices.IndexerName attribute, and the fact that you brought it up here, blaming the tool instead of your own ignorance, shows that you have a long way to go.

    The best lesson I've learned over the years is how little I know. Hopefully you will learn that lesson soon.



  • @Grimoire said:

    @dhromed said:

    Formula-1 drivers have mechanics to worry about their car, so the drivers can focus on the handling the car, as an abstracted unit, and making the best lap time.

    All F1 drivers, past and present, are excellent mechanics.  They have to be, in order to understand why their car is behaving the way it is.  Yes, the mechanics are there to solve the really tough problems, and to do all the hands on work.  But if the driver can't articulate what is happening to their car, then the mechanics can't do much.  They must have a complete understanding of their car in order to drive it to it's limit.

    I interviewed a developer for a position at our company, and we talked about how C++ implements virtual functions.  He argued that a developer shouldn't need to understand those kind of things.  I argued that you do if you ever run into a problem with virtual functions, how are you going to fix it if you don't understand how it is implemented by the compiler? At some point, the whole higher level abstraction breaks down, and you need to understand what is really going on.


    With more grey,

    The point is the distance--

    [i]point is distance? Er... Line! Surface! Hypersphere! Language topology... eh.[/i]

    --between the end-user and the core technology or principles. It's almost a given that a driver who knows about the engine is a better driver -- but up to a point. The driver should still trust that his car is in order so he can just do what he loves: driving really fast.

    To put the metaphor a little closer to home; my knowing how Photoshop [i]really[/i] works under the hood does not make me a better graphic designer. Software like that is an example of a layer of abstraction where the real structure of it is, and [i]should be[/i], completely invisible to the end-user, so I can focus on my layout skills. If the program bombs, I cannot be expected to know what the problem is, nor do I need to know a char of programming to drive Photoshop to its limits*.

    C++ is pretty low-level. An experienced developer is bound to run into virtual functions issues and knowing about how the program flows inside the hardware is a definite advantage. Would this be the case with, say, Python? Ruby?


    *) this is a big fat lie, actually. Photoshop now supports a dialect of JS for image-editing. There's even a rudimentary script editor in it, like Flash' ActionScript. I've not yet used it. I'm not enough of a visionary to understand its potential.



  • @Alex Papadimoulis said:


    That's a disturbing statement demonstrating a willful ignorance of the tool you are using. How can you expect to be a sucessful programmer if you refuse to take the time to attain a high-level understanding of what your code is doing?  This is CLR basics here, not complex MSIL stuff.

    I would not expect a programmer to know that (at least my C# books do not explicitely state that indexers result in a member called "Item" created) but I agree that a programmer should be able to find and fix the reason within a few minutes.


    The best lesson I've learned over the years is how little I know. Hopefully you will learn that lesson soon.

    The other lesson you have to learn is that you do not always need to know everything to get the job done. As have already been stated, there is more than one way to skin the cat. The important thing is to recognize the point where ignorance leads to unnecessary work (in many cases, reinvented wheels) or even more serious problems (like poor performance, unreliability etc.). Till then, as has been said in "The Matrix", ignorance is a blessing.



  • @dhromed said:


    this is a big fat lie, actually. Photoshop now supports a dialect of JS for image-editing. There's even a rudimentary script editor in it, like Flash' ActionScript. I've not yet used it. I'm not enough of a visionary to understand its potential.


    GIMP has been scriptable for years--I remember something about the fact that people who worked on the project wanted it to be very scriptable.

    A lot of the "plug-ins" for GIMP are simply scripts.

    I haven't used GIMP much more than for basic cropping and opening the odd image format I can't find a MIME type for, but I do appreciate the value of the script language--a lot of people can add functionality without having to get into the actual source.

    There's an abstraction for you.  (groan)



  • @Alex Papadimoulis said:

    @Swig said:
    Do you expect a C#
    programmer to know the machine code generated by the JIT compilation of
    their MSIL program too? No, because it's not something a high-level
    language programmer should need to concern themselves with.

    That's a disturbing statement demonstrating a willful ignorance of the tool you are using. How can you expect to be a sucessful programmer if you refuse to take the time to attain a high-level understanding of what your code is doing?  This is CLR basics here, not complex MSIL stuff.


    True, a programmer has a responsibility to understand the tools he's using.

    But it's a huge WTF that C# is designed to automatically generate an easily colliding name at all.  The original poster was exactly right:  This is what happens when syntactic sugar turns bad.  The feature does more harm than good.

    The fact that the problem trips up so many people that Microsoft is using that very case as an example on the linked MSDN page is a glaring indication that it was a mistake in language design.



  • @Alex Papadimoulis said:

    That's a disturbing statement demonstrating a willful ignorance of the tool you are using. How can you expect to be a sucessful programmer if you refuse to take the time to attain a high-level understanding of what your code is doing?  This is CLR basics here, not complex MSIL stuff.

    The "WTF" you brought up is the mistake I'd expect from a Developer I. Compound that with the name of the class ("Item"), your inability to rectify the error with a few minutes of research and the CompilerServices.IndexerName attribute, and the fact that you brought it up here, blaming the tool instead of your own ignorance, shows that you have a long way to go.

    The best lesson I've learned over the years is how little I know. Hopefully you will learn that lesson soon.



    What is the point of abstraction if you're going to learn every gory detail underlying it anyway?

    Can you sketch out on a napkin how the memory decoder in your PC works? Maybe so...but can you sketch out how the CPU's OOE scheduler works? I guarantee you that you can't. If you could, you'd be working for Intel because you would be a CPU architecture genius. There are few people in the world who understand how it works at the lowest-level, and yet it's operation affects every single thread of every process of every modern CPU core in the world.

    You have to abstract away to get anything done. You could spend decades studying how all of these systems work before writing a single line of code. It definitely helps to understand the underlying layers, but it should never be considered a prerequisite. The OP seemed to figure this problem out pretty quickly, understands what caused it, and will never do it again. He just posted here because he thought it was funny that the code that "mysteriously" broke was almost letter-for-letter the same as the code posted on MSDN...and that the cause of the error seemed to be a WTF. This is a case where somebody needed to understand the layer immediately beneath their current layer. Now that he knows he can tell the rest of his team, "Don't name classes 'Item'". They don't need to know why unless they want to.


  • @savar said:

    ...but can you sketch out how the CPU's OOE scheduler works? I guarantee you that you can't. If you could, you'd be working for Intel because you would be a CPU architecture genius. There are few people in the world who understand how it works at the lowest-level, and yet it's operation affects every single thread of every process of every modern CPU core in the world.


    There might be some point in time, maybe even in the near future, when no human in the real world really understand how it works; they might just start with a (still relatively low-level, of course) abstraction what has to be done and let a computer figure out how to layout those circuits to accomplish this goal.



  • @themagni said:

    ...The tweak saved my old company about 4 weeks of work every month.
    <font size="5">S</font>urely you mean 4 hours or 4 days of work every month?


  • ♿ (Parody)

    @savar said:

    What is the point of abstraction if you're going to learn every gory detail underlying it anyway?

    I'm not talking every gory detail. Understanding the CLR is required to be a competent .NET programmer. Thinking that this behavior is a "WTF" implies a lack of this understanding.

     

    @VGR said:

    it's a huge WTF that C# is designed to automatically generate an easily colliding name at all.  The original poster was exactly right:  This is what happens when syntactic sugar turns bad.  The feature does more harm than good.

    What else should they have done given the requirements? As demonstrated above, going with a random name will not work. They chose as generic name ("Item") that *should not* collide with the class name ("Item" is a terrible name for a class).

    If this were VB.NET we were talking about, I would say "maybe WTF." But C# is not meant to hold your hand.



  • @themagni said:

    In other words, I expect anyone who considers themselves to be a professional programmer or a Software Engineer to know what they're doing. What you're doing is making machine code. If you don't understand that and keep that in mind at all times, then you're either a Pantless Prima Donna or incompetent.

    I don't entirely agree. If you fill up your head with all that crap, you don't have enough room for things that aren't obsolete yet. That's why people a lot younger than me can write better code: they don't have to waste space in their head on all this outdated garbage, and can build a much more organised solution.

    Of course, there's a lot of stuff they simply can't write to save their lives, and that's where people like you and me come in. But you can't raise one group over the other; both are essential to the success of any forward-looking organisation.

    Yes, MS chose an exceptionally poor default name (something like _MSInternalAbstractionDefaultName would be more suitable) and the error produced is stupid. It's impossible to make a class called "item", which is exceedingly peculiar, to say the least.

    Actually, "item" is fine, it's "Item" that you have to avoid - and only if you have an indexer. An "Item" class with no indexer will work just fine.



  • Alex – sometimes Item could be a reasonable class name, certainly for an abstract base class. Consider:

    class Inventory {
     // Or whatever the generic collection is called.
     // I'm still on .Net 1.1 over here
     ArrayList<Item> stuff_in_this_inventory;
    }
    
    abstract class Item {
     ...
    }
    
    class MagicPotion : Item {
     ...
    }

    "Thinking that this behavior is a "WTF" implies a lack of this understanding."
    Even if one does understand why it's not allowed, it's still a WTF that perfectly reasonable C# code produces invalid CLR (or a compiler error to stop it producing that invalid CLR, anyway).


  • ♿ (Parody)

    @Bob Janova said:

    Alex – sometimes Item could be a reasonable class name, certainly for an abstract base class. Consider:
    class Inventory {
    // Or whatever the generic collection is called.
    // I'm still on .Net 1.1 over here
    ArrayList<Item> stuff_in_this_inventory;
    }

    abstract class Item {
    ...
    }

    class MagicPotion : Item {
    ...
    }

    Reasonable is stretching it. It's still a very poor choice. In your example, InventoryItem would be a much more approrpiate name. The word "Item" is more of a representative term than it is a class name and conveys far to much ambiguity in a semantic model. It makes as much sense as "Thing", "DooHickey", or "Entity".



  • @Alex Papadimoulis said:

    @Bob Janova said:
    Alex – sometimes Item could be a reasonable class name, certainly for an abstract base class. Consider:
    class Inventory {
    // Or whatever the generic collection is called.
    // I'm still on .Net 1.1 over here
    ArrayList<Item> stuff_in_this_inventory;
    }

    abstract class Item {
    ...
    }

    class MagicPotion : Item {
    ...
    }

    Reasonable is stretching it. It's still a very poor choice. In your example, InventoryItem would be a much more approrpiate name. The word "Item" is more of a representative term than it is a class name and conveys far to much ambiguity in a semantic model. It makes as much sense as "Thing", "DooHickey", or "Entity".


    Yes, and it seems a very poor choice for the name of an internally generated indexing class also. 


  • @triso said:

    @themagni said:
    ...The tweak saved my old company about 4 weeks of work every month.
    <font size="5">S</font>urely you mean 4 hours or 4 days of work every month?


    No, I meant what I said. I saved them 4 weeks every month. I thought about saying it twice to make it clear in my first post, but I didn't. It was for a VHF transmitter that sent IDs at varying pulse rates, that may or may not have had a motion sensor attached.

    My boss' idea was to have 1 version of the code for each ID (255 versions) for each of the possible pulse rates ( x10 ) with or without a motion sensor (x2). There was also a version of the same set of code for a different chip that had a saltwater switch. (x2) That's 10,500 versions of the code. No, I am not kidding. That was his plan.

    Every time the code had to change, it would require a recompile for each version. Yes, each version. If it took 1 minute to open, change, recompile, and rename each file, plus track each change. That's a total of 10,500 minutes to change the code. (175 hours). At 40 hours a week, that's just over 4 weeks. On average, we had to change the code about once a month. (It's a long story. Short version: It was just that kind of place.)

    I created a GUI for a hex editor that let the production staff change the ID, pulse rate, and presence of a motion sensor. I also made a second version for the saltwater switch. (I couldn't combine the two because they used different chips.) So I cut down the number of versions of the code from over 10,000 (ten thousand, not a typo) to 2 (two, not a typo)



  • @CodeRage said:


    Yes, and it (Item) seems a very poor choice for the name of an internally generated indexing class also. 

    I probably would have called it "Element", but I doubt that would make you more happy ;-)



  • A lot of commercial games do call their generic base class 'Entity'.



  • @wheels said:

    And always remember, the primary audience of a programming language is not the computer. It's the programmer writing it and other programmers that will read it. Cumulatively they will spend much more time with that source than a computer ever will.

    Both audiences are important; but the computer is the only one who will spend his time doing productive work (in terms of end-user needs) with the program, so priority one is: the computer must understand it.



  • FYI, the restriction of not having member names the same as type names does not exist at the opcode level, the restriction is at the language level. You can implement a class in J# that has the same member name as its type, and use that as you would expect in c#. The developers could have extended this exception to c# for this one case, but probably felt it better not to.

    Java can have this problem if you add a variable that matches a synthetic one in a previous version, forcing java to rename the synthetic one (not entirly sure about this). Java uses synthetic names for outer class references.



  • @subanark said:

    Java can have this problem if you add a variable that matches a synthetic one in a previous version, forcing java to rename the synthetic one (not entirly sure about this). Java uses synthetic names for outer class references.


    Which is why you shouldn't (can't with javac?) use variable/method/class names that have a $ in them - all synthetic items have one, so that is an easy way of preventing conflicts.

    Also, why the heck doesn't C# allow a member with the same name as the class? That seems like an arbitrary and useless restriction.



  • @wheels said:

    Whoever told you binary isn't an abstraction is wrong. We're not really producing machine code or binary, we're pushing waves down wires. Of course, those waves and wires are abstractions too.

    And apparently even that abstraction is leaky in certain circumstances (i.e. metastability in asynchronous circuits or ones with more than one clock).


Log in to reply