Inheritance impossible in Windows Runtime Component? - c#

Scenario:
I have 3 classes (A,B,C) in my Windows Runtime Component project.
class A{}
public sealed class B : A {}
public sealed class C : A {}
On compiling the above code, I get the following error:
"Inconsistent accessibility: base class 'A' is less accessible than
class 'C'."
If I make class A public, it gives a compile error :
"Exporting unsealed types is not supported. Please mark type
'MyProject.A' as sealed."
But now, if I make A as sealed, then B and C cannot inherit from it.
Considering the fact that only WinRT types are allowed for inheritance, is it anyhow possible to use custom/user-defined classes for inheritance? If not, is there any workaround to achieve the same?

As you've figured out by yourself, you can't expose classes that inherit from others in a Windows Runtime Component; that is true even if you try to use an abstract class as a parent class.
This is a "drawback" needed to make WinRT components works with all the others languages that the WinRT framework supports.
The only way to workaround this is avoiding inheritance.
You can only use interfaces or object composition where you can simulate inheritance behaviors, e.g.:
public sealed class A
{
public void Method() { }
}
public sealed class B
{
A a;
public void Method()
{
// Do B stuff
// Call fake "virtual" method
a.Method();
}
}

Related

WinForms Export UserControl derived class, but not in-between classes

I have a DLL that I'm making for Windows Forms applications. The layout looks a little something like this
public class A : UserControl
{
protected C c;
}
public class B : A { }
public class C { }
I want the DLL to only export class B, but it will not compile if I remove the public qualifier from A or C. Is there a way to do this?
Error from removing public from A:
Error CS0060 Inconsistent accessibility: base class 'A' is less accessible than class 'B'
From MSDN - Restrictions on Using Accessibility Levels (C# Reference):
When you specify a type in a declaration, check whether the accessibility level of the type is dependent on the accessibility level of a member or of another type. For example, the direct base class must be at least as accessible as the derived class.
Usually, in order to hide "stuff" from others, what you do, is provide a public interface and hide all the sub-classes. You can let your client create the concrete classes with a public factory which you will provide as well.
Not possible. If B inherits A, you simply cannot expose B without exposing A.

Why can't I inherit from a private class / interface?

Why is this illegal in C#?
class Foo: Foo.BaseFoo //Circular base class dependency compile time error
{
private class BaseFoo {...}
...
}
I'm not arguing when this could be useful or not, but I'd like to know what are the reasons that would disallow such code to compile. A similar restriction happens with private interfaces.
UPDATE
Seeing that its a duplicate I'll center the question more in why this isn't valid with interfaces which seems more useful?
And, what's more, why does it seem to be legal with the Roslyn preview as shown here
This is not a problem of the access modifier -that the class is private. This is a circular base class dependency. You try to define a class called Foo that inherits a nested class called BaseFoo.

Adding private method to class by inheritance in C#

I asked this question yesterday, but I think it was unclear what my primary concern was. In C++, we have private and multiple inheritance, which enables us to add private methods to classes by just inheriting from the class declaring these methods. That is, if there's a class
class B {
public:
virtual void doMethodB();
};
and a class
class A : private B {
virtual int doMethodA();
};
doMethodB() can be called from within doMethodA(), but is not accessible from outside.
Now, I'd like to mimic this behavior in C#. There is no multiple nor private inheritance. Up to know, I can think of four way to achieve somthing similar, but still with serious drawbacks:
First: Use an interface, i.e.
interface IB {
public void doMethodB();
};
class A : IB {
public void doMethodB();
int doMethodA();
};
However, when we do this, doMethodB() is public, and must be implemented in each class inheriting from IB.
Second: Use a static method
public static class B {
public static void doMethodB();
};
That way, there need only be one implementation, but the method is still public and can't be restricted to certain classes.
Third: Use a extension method, like that. That way however, the method is called on the object (i.e. a.doMethodB()) and not from "inside".
Fourth: Composition.
class A {
private B b;
public int doMethodA();
};
Now, B's methods can be called like b.doMethodB() from A only, but are other issues now regarding serialization, b == null etc.
Is there another alternative? And if not, which one among the presented ones would you consider "the best"?
Regarding your "First" proposal with interfaces: you can also implement the interface explicitly:
"A class that implements an interface can explicitly implement a member of that interface. When a member is explicitly implemented, it cannot be accessed through a class instance, but only through an instance of the interface. "
See / Source: http://msdn.microsoft.com/en-us/library/aa288461%28v=vs.71%29.aspx
However, i would choose the Composition approach. "Favor Composition over Inheritance", also see Prefer composition over inheritance?
Ideally, i would constructor-inject B into A by dependency injection, that should help mitigate your b == null concern.
Note:
Using a static method / extension method (is a static method, too...) makes unit-testing A (respectively faking B) very hard, which is why i would forgo these solutions completely.
Edit:
If you don't need B.doMethodB accessible from anyone else than A, you can also make B an abstract class and B.doMethodB a protected method.
But i was thinking that you already know that ;-)
(And because of the testing issues i would still favor composition over inheritance).
I think the concept you are looking for is the protected access modifier. It means that only B itself and its derived classes can access the method, but others cannot.
class B {
protected virtual void DoMethodB() {}
}
class A : B {
virtual void DoMethodA() {
DoMethodB();
}
}
If you wanted, you can further restrict the access to protected internal which means that the method can only be accessed from derived classes inside your assembly.
Also, be aware of the consequences of virtual methods. If there is no explicit need to make a method virtual, it should not be marked virtual.

C# private (hidden) base class

Is it possible to make a C# base class accessible only within the library assembly it's compiled into, while making other subclasses that inherit from it public?
For example:
using System.IO;
class BaseOutput: Stream // Hidden base class
{
protected BaseOutput(Stream o)
{ ... }
...lots of common methods...
}
public class MyOutput: BaseOutput // Public subclass
{
public BaseOutput(Stream o):
base(o)
{ ... }
public override int Write(int b)
{ ... }
}
Here I'd like the BaseOutput class to be inaccessible to clients of my library, but allow the subclass MyOutput to be completely public. I know that C# does not allow base classes to have more restrictive access than subclasses, but is there some other legal way of achieving the same effect?
UPDATE
My solution for this particular library is to make the base class public and abstract, and to document it with "Do not use this base class directly". I also make the constructor of the base class internal, which effectively prevents outside clients from using or inheriting the class.
(It's a shame, because other O-O languages let me have hidden base classes.)
Unfortunately not. You can't derive a public class from an internal or private class.
You need to either expose the base class, or you need to declare all the methods for all of your similar classes. If you go the route where you declare all methods again, it's probably useful to create a helper class, which has the actual implementation of them. Still it's quite a bit of boilerplate.
Consider a pattern such as a Facade. That's what they're there for. I don't think you can achieve what you require with straight inheritance.
Depending on what "lot of common methods" are doing you may achieve some of it with internal extension methods:
internal static class MyStreamExtensions
{
internal static int UsefulOne(this Stream stream)
{
return 42;
}
}
Another approach is to make constructor internal to prevent unintentional derivation from that class:
public class BaseOutput: Stream
{
internal BaseOutput(Stream o)
{ ... }
...lots of common methods...
}
This will make code more understandable compared to "not-really-visible" intermediate class in hierarchy.

Why can't I have a public class that inherits from an internal class?

I do not understand the accessibility limitations exhibited below
public abstract class Base { }
internal class Common : Base { }
public class Instance : Common { }
This won't compile.
Inconsistent accessibility: base class 'Common' is less accessible than class 'Instance'
I can accomplish what I wanted with public abstract class Common but why can't I simply not expose the name at all?
Edit: What I'm asking is WHY it works this way! Everyone is answering with what the rules are, not explaining why the rules are that way.
Inheritors of a class cannot widen the scope of accessibility of the base class.
public: Access not limited
internal: Access limited to this program
Once limited to the program, all inheritors of a, internal class must remain internal or assume lesser accessibility (protected internal or private).
Per the C# specification, section §3.5.4 Accessibility constraints:
The parameter types of an instance constructor must be at least as
accessible as the instance constructor itself.
In the example
class A {...}
public class B: A {...}
the B class results in a compile-time error because A is not at least
as accessible as B.
Also:
The direct base class of a class type must be at least as accessible
as the class type itself (§3.5.2). For example, it is a compile-time
error for a public class to derive from a private or internal class.
If you are trying to create a Common class with functionality you prefer not to make accessible to external code, you should prefer composition over inheritance. For example:
public abstract class Base
{
...
}
internal class Common : Base
{
...
}
public class Instance
{
internal Instance(Common common)
{
...
}
...
}
It's a matter of how visible the code is to other assemblies. By making Common internal you're limiting access to Common to its assembly whereas by making Instance public you're making Instance accessible to any referencing assembly. If a referencing assembly can't access a type's base class how could it access any members inherited from that base class?
If Common contained a property, lets say Foo:
public string Foo { get; set; }
than the Instance class would automatically expose that property. You can think of it this way:
public void Test()
{
Common myInstance = new Instance();
System.Console.WriteLine(myInstance.Foo);
}
Since Instance needs to expose everything Common has, the access modifier on the base class cannot be less exposed.
You could, however, create the property Foo as internal to accomplish much the same.

Categories

Resources