Ask a questionAsk a question
 

AnswerMistake in C# Language

  • Monday, November 02, 2009 4:50 PMajaytemp Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    abstract class MyClass1

    internal abstract void AMethod();
    }

    abstract class MyClass2 : MyClass1
    {
    internal abstract new void AMethod();
    }

    class MyClass3 : MyClass2
    {
    // does not compile
    internal new void AMethod() { } // override void AMethod() { } does not work either!
    }

    With these definitions, it is not possible to build a concrete class!


    A new refurbished computer for everyone!
    • Edited byajaytemp Monday, November 02, 2009 5:33 PMforgot to add internal
    •  

Answers

  • Tuesday, November 03, 2009 9:00 AMLouis.fr Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Which compiler are you using?
    MyClass2 should not compile.

    After verification, the C# specification does not explicitly forbid hiding abstract members, but since an abstract member must be implemented by non-abstract classes derived from it, the compiler should prevent this. The compiler from Microsoft throws a CS0533 error.
    • Marked As Answer byajaytemp Tuesday, November 03, 2009 5:35 PM
    •  
  • Tuesday, November 03, 2009 5:50 PMajaytemp Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Rudedog:

    Changing your code in the original post is not playing fair.
    I believe that this was the original code.
    It does not compile with MyClass3 commented out of the picture because you hide an abstract member.


            abstract class MyClass1
            {
                public abstract void AMethod();
            }

            abstract class MyClass2 : MyClass1
            {
                public abstract new void AMethod();
            }

            class MyClass3 : MyClass2
            {
                // does not compile
                internal new void AMethod()
                {
                } // override void AMethod() { } does not work either!
            }


    I do not understand the point of arguments.  Think you found a compiler bug?
    Here's another implementation that might be whatever it is that you are after.



        interface IMyInterface
        {
            void AMethod();
        }
        abstract class MyClass1 : IMyInterface
        {
            public abstract void AMethod();        
        }

        abstract class MyClass2 : MyClass1, IMyInterface
        {
            void IMyInterface.AMethod()
            {
            }
        }
        // this class does compile
        class MyClass3 : MyClass2
        {
            public override void AMethod()
            {
            }
        }


    You will need to access some class members of object instances "through the interface" in order to use them..

    Hope this helps.

    Rudy  =8^D
    Mark the best replies as answers. "Fooling computers since 1971."

    That example below, that compiles, is not very relevant.

    This thread is answered. 

    Louis.FR
    "After verification, the C# specification does not explicitly forbid hiding abstract members, but since an abstract member must be implemented by non-abstract classes derived from it, the compiler should prevent this."

    The point is that C# compiler does not flag this as an error while VB compiler does.  Is that a compiler bug?  Not necessarily because the C# specification does not forbid it.  A language flaw.  Perhaps.
    A new refurbished computer for everyone!
    • Marked As Answer byajaytemp Tuesday, November 03, 2009 5:57 PM
    • Edited byajaytemp Tuesday, November 03, 2009 6:11 PM
    •  

All Replies

  • Monday, November 02, 2009 4:53 PMLouis.fr Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    You cannot hide an abstract method. MyClass2 won't compile.
    • Proposed As Answer byRudedog2ModeratorTuesday, November 03, 2009 4:23 PM
    • Unproposed As Answer byajaytemp Tuesday, November 03, 2009 5:35 PM
    •  
  • Monday, November 02, 2009 5:40 PMRudedog2ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Louis.fr is correct.  The method must be implemented, not hidden.
    Here's similar code that does compile.


        interface IMyInterface
        {
            void AMethod();
        }
        abstract class MyClass1 : IMyInterface
        {
            public virtual void AMethod()
            {
            }
        }

        abstract class MyClass2 : MyClass1
        {
            public override void AMethod()
            {
            }
        }

        class MyClass3 : MyClass2
        {
            // does compile
            public override void AMethod()
            {
            }
        }


    Rudedog   =8^D

    Mark the best replies as answers. "Fooling computers since 1971."
  • Monday, November 02, 2009 8:27 PMajaytemp Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    MyClass2 compiles in C# not VB.
    A new refurbished computer for everyone!
  • Monday, November 02, 2009 8:36 PMRudedog2ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    The code I posted for MyClass2 compiles in C#. 
    AS IS, it should not work with a VB compiler.  A C# to VB translation is needed.
    Mark the best replies as answers. "Fooling computers since 1971."
  • Monday, November 02, 2009 8:48 PMajaytemp Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    No, i wrote it in VB and it does not compile.  But the actual C# code in the first post does compile without MyClass3.
    A new refurbished computer for everyone!
  • Monday, November 02, 2009 8:57 PMRudedog2ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    You are not making sense. 
    I am terrible at reading minds and between the lines.

    Your line of questions is going off-topic from your original question.
    Off-topic for the C# forums.  How to code in Visual Basic.

    So we now have a VB bug?

    Mark the best replies as answers. "Fooling computers since 1971."
  • Monday, November 02, 2009 9:37 PMajaytemp Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Very easy.  The C# code compiles.  BUT there is no use for the abstract class MyClass2 because I cannot extend it.
    The code translated into VB does not compile which is the correct compiler action.

    Louis.FR:
    "You cannot hide an abstract method. MyClass2 won't compile."

    This is not true.  MyClass2 will compile.


    A new refurbished computer for everyone!
  • Tuesday, November 03, 2009 9:00 AMLouis.fr Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Which compiler are you using?
    MyClass2 should not compile.

    After verification, the C# specification does not explicitly forbid hiding abstract members, but since an abstract member must be implemented by non-abstract classes derived from it, the compiler should prevent this. The compiler from Microsoft throws a CS0533 error.
    • Marked As Answer byajaytemp Tuesday, November 03, 2009 5:35 PM
    •  
  • Tuesday, November 03, 2009 3:19 PMajaytemp Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    I compiled in Microsoft Visual Studio 2008 SP1.


    A new refurbished computer for everyone!
  • Tuesday, November 03, 2009 3:51 PMLouis.fr Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    You changed your code.

    This won't compile:

    abstract class MyClass2 : MyClass1
    {
        public abstract new void AMethod();
    }

    If the method is protected, it won't compile either.
    You cannot hide an abstract method with a publicly available method because people inheriting from your class need to be able to implement MyClass1.AMethod()

    If MyClass2.AMethod() is not publicly available, then it has no effect on anyone but you because the method is only hidden within its scope.
    In that context, it becomes an error only when you try to inherit from MyClass2.

    Reminds me of something similar about hiding and scope:

    public class C1
    {
        public virtual string GetMyName()
        {
            System.Console.Out.WriteLine("C1");
        }
    }

    public class C2
    {
        new string GetMyName()
        {
            System.Console.Out.WriteLine("C2");
        }
    }

    public class Program
    {
        public void Main()
        {
            new C2().GetMyName();
        }
    }

    C2.GetMyName hides C1.GetMyName but the call in Main() never gets to it.

    • Proposed As Answer byRudedog2ModeratorTuesday, November 03, 2009 4:23 PM
    • Unproposed As Answer byajaytemp Tuesday, November 03, 2009 5:57 PM
    •  
  • Tuesday, November 03, 2009 4:23 PMRudedog2ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Changing your code in the original post is not playing fair.
    I believe that this was the original code.
    It does not compile with MyClass3 commented out of the picture because you hide an abstract member.


            abstract class MyClass1
            {
                public abstract void AMethod();
            }

            abstract class MyClass2 : MyClass1
            {
                public abstract new void AMethod();
            }

            class MyClass3 : MyClass2
            {
                // does not compile
                internal new void AMethod()
                {
                } // override void AMethod() { } does not work either!
            }


    I do not understand the point of arguments.  Think you found a compiler bug?
    Here's another implementation that might be whatever it is that you are after.



        interface IMyInterface
        {
            void AMethod();
        }
        abstract class MyClass1 : IMyInterface
        {
            public abstract void AMethod();        
        }

        abstract class MyClass2 : MyClass1, IMyInterface
        {
            void IMyInterface.AMethod()
            {
            }
        }
        // this class does compile
        class MyClass3 : MyClass2
        {
            public override void AMethod()
            {
            }
        }


    You will need to access some class members of object instances "through the interface" in order to use them..

    Hope this helps.

    Rudy  =8^D
    Mark the best replies as answers. "Fooling computers since 1971."
  • Tuesday, November 03, 2009 5:50 PMajaytemp Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Rudedog:

    Changing your code in the original post is not playing fair.
    I believe that this was the original code.
    It does not compile with MyClass3 commented out of the picture because you hide an abstract member.


            abstract class MyClass1
            {
                public abstract void AMethod();
            }

            abstract class MyClass2 : MyClass1
            {
                public abstract new void AMethod();
            }

            class MyClass3 : MyClass2
            {
                // does not compile
                internal new void AMethod()
                {
                } // override void AMethod() { } does not work either!
            }


    I do not understand the point of arguments.  Think you found a compiler bug?
    Here's another implementation that might be whatever it is that you are after.



        interface IMyInterface
        {
            void AMethod();
        }
        abstract class MyClass1 : IMyInterface
        {
            public abstract void AMethod();        
        }

        abstract class MyClass2 : MyClass1, IMyInterface
        {
            void IMyInterface.AMethod()
            {
            }
        }
        // this class does compile
        class MyClass3 : MyClass2
        {
            public override void AMethod()
            {
            }
        }


    You will need to access some class members of object instances "through the interface" in order to use them..

    Hope this helps.

    Rudy  =8^D
    Mark the best replies as answers. "Fooling computers since 1971."

    That example below, that compiles, is not very relevant.

    This thread is answered. 

    Louis.FR
    "After verification, the C# specification does not explicitly forbid hiding abstract members, but since an abstract member must be implemented by non-abstract classes derived from it, the compiler should prevent this."

    The point is that C# compiler does not flag this as an error while VB compiler does.  Is that a compiler bug?  Not necessarily because the C# specification does not forbid it.  A language flaw.  Perhaps.
    A new refurbished computer for everyone!
    • Marked As Answer byajaytemp Tuesday, November 03, 2009 5:57 PM
    • Edited byajaytemp Tuesday, November 03, 2009 6:11 PM
    •  
  • Tuesday, November 03, 2009 5:57 PMajaytemp Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Louis.FR

    You changed your code.

    This won't compile:

    abstract class MyClass2 : MyClass1
    {
        public abstract new void AMethod();
    }

    If the method is protected, it won't compile either.
    You cannot hide an abstract method with a publicly available method because people inheriting from your class need to be able to implement MyClass1.AMethod()

    If MyClass2.AMethod() is not publicly available, then it has no effect on anyone but you because the method is only hidden within its scope.
    In that context, it becomes an error only when you try to inherit from MyClass2.

    Reminds me of something similar about hiding and scope:

    public class C1
    {
        public virtual string GetMyName()
        {
            System.Console.Out.WriteLine("C1");
        }
    }

    public class C2
    {
        new string GetMyName()
        {
            System.Console.Out.WriteLine("C2");
        }
    }

    public class Program
    {
        public void Main()
        {
            new C2().GetMyName();
        }
    }

    C2.GetMyName hides C1.GetMyName but the call in Main() never gets to it.


    That example is not relevant either.  I can invoke GetMyName() through another class method.

    In my example, the abstract class cannot be implemented.  This is apples and oranges.
    A new refurbished computer for everyone!
  • Tuesday, November 03, 2009 6:02 PMRudedog2ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    The C# compiler does and did flag an error before you modified your code.  The error code was CS0533, hides inherited abstract member.
    Changing the access modifier must have imposed a different set of rules.  I might research it later.

    You keep citing code that you have not posted, written in VB.
    The behavior of the VB compiler is kinda, sort-of, off-topic in C# forums.  Lack of interest.  "It's not my fault!"

    Glad you found an answer, but it didn't seem satisfactory enough.

    Mark the best replies as answers. "Fooling computers since 1971."
  • Tuesday, November 03, 2009 6:06 PMajaytemp Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    You changed your code.

    This won't compile:

    abstract class MyClass2 : MyClass1
    {
        public abstract new void AMethod();
    }

    If the method is protected, it won't compile either.
    You cannot hide an abstract method with a publicly available method because people inheriting from your class need to be able to implement MyClass1.AMethod()

    If MyClass2.AMethod() is not publicly available, then it has no effect on anyone but you because the method is only hidden within its scope.
    In that context, it becomes an error only when you try to inherit from MyClass2.

    Reminds me of something similar about hiding and scope:

    public class C1
    {
        public virtual string GetMyName()
        {
            System.Console.Out.WriteLine("C1");
        }
    }

    public class C2
    {
        new string GetMyName()
        {
            System.Console.Out.WriteLine("C2");
        }
    }

    public class Program
    {
        public void Main()
        {
            new C2().GetMyName();
        }
    }

    C2.GetMyName hides C1.GetMyName but the call in Main() never gets to it.


    "If MyClass2.AMethod() is not publicly available, then it has no effect on anyone but you because the method is only hidden within its scope.
    In that context, it becomes an error only when you try to inherit from MyClass2."

    True, however, if the abstract class cannot be inherited from it has no value whatsoever within it scope.  What's the point of it if I can't inherit from it? 
    A new refurbished computer for everyone!
  • Tuesday, November 03, 2009 6:17 PMRudedog2ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I told you it flagged an error.

    Any member declared as 'abstract' is supposed to be declared as public.

    Mark the best replies as answers. "Fooling computers since 1971."
  • Wednesday, November 04, 2009 8:36 AMLouis.fr Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    The true problem is that the compiler doesn't react if you declare an abstract method as internal.
    The VB compiler doesn't react either.

    Afterthought: declaring an abstract method as internal can be useful to prevent users of your library to derive from your class, without declaring it as sealed, and then allowing you from deriving from it.
  • Wednesday, November 04, 2009 10:01 AMLouis.fr Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    An example of such underivable abstract classes is here:

    http://msdn.microsoft.com/en-us/library/system.windows.forms.filedialog.aspx

    "Although the class is declared public, you cannot inherit from it, as it contains internal abstract methods.."