C# private (hidden) base class - c#

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.

Related

Base class or common class?

for our asp.net web application v 4.0, we are in process of defining a class that contains methods that are common across the application. to achieve this there are 2 Suggestions within our team.. one to create a base class, define the methods in that and derive all the other classes from that base class.. the other one is to create a seperate class (not a base class) and instantiate that common class in other classes when required to access the common methods. Please guide me in identifying the best approach..
I'd only go the base class route if there is a real is-a relationship between the base class and the derived classes. One reason is that a class can only inherit from a single base class. I'd use this relationship in a sensible way. Just sharing some helper methods is not a scenario worth blocking this relationship.
If you want to use some helper methods in several classes, composition is the better way as you describe in the 2nd approach. Instead of creating the objects in the classes, you should think about whether you can inject the instances into the classes (see this link for details on dependency injection), e.g.:
public class HelperClass
{
public virtual void HelperMethod()
{
// ...
}
}
public class ClassThatUsesHelper
{
private readonly HelperClass _helper;
public ClassThatUsesHelper(HelperClass helper)
{
_helper = helper;
}
public void DoSomething()
{
_helper.HelperMethod();
}
}
By injecting the helper class you decouple the classes so that you can substitute the helper class by a different implementation that shares the same interface. ClassThatUsesHelper works with any class that is derived from HelperClass (or HelperClass itself of course). So if you need to decorate the helper method or need a special implementation in some cases, this is possible without any problem.
Using composition also enables you to test the helper methods separately.
However, if it is about very basic helper methods, you might also think about having a static class with static helper methods. Please note that you introduce a strong dependency between the classes and that you cannot adjust the implementation easily.
public static class HelperClass
{
public static void HelperMethod()
{
// ...
}
}
public class ClassThatUsesHelper
{
public void DoSomething()
{
HelperClass.HelperMethod();
}
}
Your question is vague, but if you need a method which all objects in your program will need to have access to, that uses their member variables, then I wold recommend creating an abstract class upon which your objects are based.
If you need a means of performing some sort of calculation from anywhere in your code, just create a public static method in a class meant for the purpose. MyMathClass.InterestingFourierTransform(), for example.

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.

How to prevent an abstract class with public derived classes from being inherited in other assemblies?

I want to write something like the following:
internal class InternalData
{
}
public class PublicData
{
}
abstract internal class Base {
internal Base() { }
private static InternalData CreateInternalDataFromPublicData(PublicData publicData)
{
throw new NotImplementedException();
}
abstract protected void DoProcess(InternalData internalData);
public void Process(PublicData publicData)
{
InternalData internalData = CreateInternalDataFromPublicData(publicData);
DoProcess(internalData);
}
}
public sealed class Derived : Base
{
protected override void DoProcess(InternalData internalData)
{
throw new NotImplementedException();
}
}
That is, Base contains some internal logic and is not intended to be inherited by classes outside of my assembly; and Derived is accessible from the outside.
InternalData also contains some internal logic and, as it would (and should) never be used from the outside, i also want to make it internal.
Of course the code above won't compile as the Base should not be less accessible than Derived. I can set the Base to be public, that's fine, but it leads to another problem.
If Base is public, then there could possibly be some ExternalDerived : Base in some other assembly. But Base.DoProcess accepts an InternalData as its argument, so that ExternalDerived cannot implement it (as it doesn't know about the InternalData).
Internal parameterless Base constructor prevents creation of any ExternalDerived instances, and thus nobody will implement ExternalDerived.DoProcess and no InternalData public exposure is needed, but the compiler doesn't know it.
How can i rewrite the code above so that there will be an abstract DoProcess(InternalData) method and so that InternalData class will be internal?
Since C# 7.2 there is private protected access modifier, which means "available only to derived classes in the same assembly".
In other words, it must meet conditions for both internal AND protected, unlike protected internal which applies to internal OR protected.
You can mark the base class' constructor as private protected, effectively preventing inheritance of that class through this constructor outside the assembly while still allowing inheritance within that assembly (and the assembly's friends).
So, a class like this:
public abstract BaseClass
{
private protected BaseClass() {}
}
is effectively sealed outside the assembly, while still inheritable within the assembly.
To make InternalData internal, DoProcess must be private or internal
(or InternalAndProtected, but C# doesn't support this CLR feature). It can't be protected or protected internal.
internal abstract DoProcess(InternalData internalData);
I'd probably also add an internal abstract void DoNotInheritFromThisClassInAnOutsideAssembly() member. That prevents anybody outside the assembly from inheriting from your class, because they can't implement that member and they get a reasonable compiler error. But you can't make the Base class itself internal.
I'd consider refactoring the code, so that you have no common base class. Probably by using some internal interfaces and composition.
It smells like you should use composition instead of inheritance. sorry, this is a very vague answer. I'm thinking more about this now..
The base type must be accessible, because otherwise, it becomes impossible to figure out its base. Your Base derives directly from System.Object, but how does a user of Derived know that? How does it know that Base doesn't derive from another public type, and that type's members should be made available?
If you mark everything in Base internal, except for the class itself, you've already prevented other assemblies from doing anything useful with it. In other words, if you make DoProcess internal, you can then prevent InternalData from becoming public.
Yes, admittedly this allows for bugs in your own assembly, if other classes try to call DoProcess. Unfortunately, there is no "accessible from derived classes in the same assembly" access modifier, only "accessible from derived classes", "accessible from the same assembly" and "accessible from derived classes and accessible from the same assembly". (Actually, .NET does support it, but C# doesn't.)
Set Base to be public.
public abstract class Base {...
Change Base.DoProcess:
protected virtual void DoProcess<T>(T internalData)
{
if (!(internalData is InternalData))
{
throw new ArgumentOutOfRangeException("internalData");
}
}
Change Derived.DoProcess:
protected override void DoProcess<T>(T internalData)
{
base.DoProcess(internalData);
// Other operations
}
It is actually quite straight forward. You just require that a deriving class implement an abstract internal method. Classes outside the library won't be able to implement the abstract method, and thus fail at compile time.
Your example, minimized to just the essentials:
abstract internal class Base {
internal protected abstract void DoProcess();
public void Process() {
DoProcess();
}
}
public sealed class Derived : Base {
internal protected override void DoProcess() {
throw new NotImplementedException();
}
}

c# Factory Method and protection levels problem

I have a base class and several subclasses derived from that base class. I also have a static function in the base class that takes some parameters, and instantiates and returns an appropriate subclass based on input parameters ( my factory method.)
Now here's my problem: I want to ONLY allow instantiation of the subclasses FROM the factory method. But if I set the constructors of the subclasses to be protected, the base class can't see them. Is there an access modifier I'm missing that would allow the base class to call the subclasses constructors, but not not allow any other classes to call them?
Internal doesn't look like it will work either...I want to limit access to the subclass constructors to just the base class, there are other classes in the same assembly that should be able to access the base factory method and but not directly instantiate any of the subclasses.
Hopefully there's something really simple I'm missing...
Example:
public class Base
{
public Base CreateChild(string childType)
{
if(childType == "A")
return new ChildA();
if(childType == "B")
return new ChildB();
return null;
}
}
public class ChildA
{
protected ChildA() // This doesn't work, since now base class can't call this!
{
}
}
public class ChildB
{
protected ChildB()
{
}
}
You can declare the child classes as private nested classes inside Base
Have you tried declaring the child classes within the base class?
public class Base {
protected class ChildA {}
protected class ChildB {}
}
If accessing any derived object through the base type is a valid scenario (let's say derived types only override base implementations and do not add new functionality) then the proposed solution of making the derived types nested private classes (as previous answers propose) is the best solution.
If that's not the case then I think you are falling into a case of unjustified complexity. What is the reason why code from your same assembly can not access ChildA and ChildB constructors? It is after all code you can control, so you can always choose to make / enforce via code review that he initalization is through the factory method.
I understand there is valid reasons to not let external assemblies freely instantiate objects except through a tightly controlled mechanism. In this case just marking the constructors as internal would do.
Otherwise, I'm not sure you can achieve what you are pretending without creating a specific assembly just for this base class and its derived classes. There is definitely no access modifier that would make a static method in a derived class only visible from it's base class.

Why can't I inherit static classes?

I have several classes that do not really need any state. From the organizational point of view, I would like to put them into hierarchy.
But it seems I can't declare inheritance for static classes.
Something like that:
public static class Base
{
}
public static class Inherited : Base
{
}
will not work.
Why have the designers of the language closed that possibility?
Citation from here:
This is actually by design. There seems to be no good reason to inherit a static class. It has public static members that you can always access via the class name itself. The only reasons I have seen for inheriting static stuff have been bad ones, such as saving a couple of characters of typing.
There may be reason to consider mechanisms to bring static members directly into scope (and we will in fact consider this after the Orcas product cycle), but static class inheritance is not the way to go: It is the wrong mechanism to use, and works only for static members that happen to reside in a static class.
(Mads Torgersen, C# Language PM)
Other opinions from channel9
Inheritance in .NET works only on instance base. Static methods are defined on the type level not on the instance level. That is why overriding doesn't work with static methods/properties/events...
Static methods are only held once in memory. There is no virtual table etc. that is created for them.
If you invoke an instance method in .NET, you always give it the current instance. This is hidden by the .NET runtime, but it happens. Each instance method has as first argument a pointer (reference) to the object that the method is run on. This doesn't happen with static methods (as they are defined on type level). How should the compiler decide to select the method to invoke?
(littleguru)
And as a valuable idea, littleguru has a partial "workaround" for this issue: the Singleton pattern.
The main reason that you cannot inherit a static class is that they are abstract and sealed (this also prevents any instance of them from being created).
So this:
static class Foo { }
compiles to this IL:
.class private abstract auto ansi sealed beforefieldinit Foo
extends [mscorlib]System.Object
{
}
Think about it this way: you access static members via type name, like this:
MyStaticType.MyStaticMember();
Were you to inherit from that class, you would have to access it via the new type name:
MyNewType.MyStaticMember();
Thus, the new item bears no relationships to the original when used in code. There would be no way to take advantage of any inheritance relationship for things like polymorphism.
Perhaps you're thinking you just want to extend some of the items in the original class. In that case, there's nothing preventing you from just using a member of the original in an entirely new type.
Perhaps you want to add methods to an existing static type. You can do that already via extension methods.
Perhaps you want to be able to pass a static Type to a function at runtime and call a method on that type, without knowing exactly what the method does. In that case, you can use an Interface.
So, in the end you don't really gain anything from inheriting static classes.
Hmmm... would it be much different if you just had non-static classes filled with static methods..?
What you want to achieve by using class hierarchy can be achieved merely through namespacing. So languages that support namespapces ( like C#) will have no use of implementing class hierarchy of static classes. Since you can not instantiate any of the classes, all you need is a hierarchical organization of class definitions which you can obtain through the use of namespaces
You can use composition instead... this will allow you to access class objects from the static type. But still cant implements interfaces or abstract classes
Although you can access "inherited" static members through the inherited classes name, static members are not really inherited. This is in part why they can't be virtual or abstract and can't be overridden. In your example, if you declared a Base.Method(), the compiler will map a call to Inherited.Method() back to Base.Method() anyway. You might as well call Base.Method() explicitly. You can write a small test and see the result with Reflector.
So... if you can't inherit static members, and if static classes can contain only static members, what good would inheriting a static class do?
A workaround you can do is not use static classes but hide the constructor so the classes static members are the only thing accessible outside the class. The result is an inheritable "static" class essentially:
public class TestClass<T>
{
protected TestClass()
{ }
public static T Add(T x, T y)
{
return (dynamic)x + (dynamic)y;
}
}
public class TestClass : TestClass<double>
{
// Inherited classes will also need to have protected constructors to prevent people from creating instances of them.
protected TestClass()
{ }
}
TestClass.Add(3.0, 4.0)
TestClass<int>.Add(3, 4)
// Creating a class instance is not allowed because the constructors are inaccessible.
// new TestClass();
// new TestClass<int>();
Unfortunately because of the "by-design" language limitation we can't do:
public static class TestClass<T>
{
public static T Add(T x, T y)
{
return (dynamic)x + (dynamic)y;
}
}
public static class TestClass : TestClass<double>
{
}
You can do something that will look like static inheritance.
Here is the trick:
public abstract class StaticBase<TSuccessor>
where TSuccessor : StaticBase<TSuccessor>, new()
{
protected static readonly TSuccessor Instance = new TSuccessor();
}
Then you can do this:
public class Base : StaticBase<Base>
{
public Base()
{
}
public void MethodA()
{
}
}
public class Inherited : Base
{
private Inherited()
{
}
public new static void MethodA()
{
Instance.MethodA();
}
}
The Inherited class is not static itself, but we don't allow to create it. It actually has inherited static constructor which builds Base, and all properties and methods of Base available as static. Now the only thing left to do make static wrappers for each method and property you need to expose to your static context.
There are downsides like the need for manual creation of static wrapper methods and new keyword. But this approach helps support something that is really similar to static inheritance.
P.S.
We used this for creating compiled queries, and this actually can be replaced with ConcurrentDictionary, but a static read-only field with its thread safety was good enough.
My answer: poor design choice. ;-)
This is an interesting debate focused on syntax impact. The core of the argument, in my view, is that a design decision led to sealed static classes. A focus on transparency of the static class's names appearing at the top level instead of hiding ('confusing') behind child names? One can image a language implementation that could access the base or the child directly, confusing.
A pseudo example, assuming static inheritance was defined in some way.
public static class MyStaticBase
{
SomeType AttributeBase;
}
public static class MyStaticChild : MyStaticBase
{
SomeType AttributeChild;
}
would lead to:
// ...
DoSomethingTo(MyStaticBase.AttributeBase);
// ...
which could (would?) impact the same storage as
// ...
DoSomethingTo(MyStaticChild.AttributeBase);
// ...
Very confusing!
But wait! How would the compiler deal with MyStaticBase and MyStaticChild having the same signature defined in both? If the child overrides than my above example would NOT change the same storage, maybe? This leads to even more confusion.
I believe there is a strong informational space justification for limited static inheritance. More on the limits shortly. This pseudocode shows the value:
public static class MyStaticBase<T>
{
public static T Payload;
public static void Load(StorageSpecs);
public static void Save(StorageSpecs);
public static SomeType AttributeBase
public static SomeType MethodBase(){/*...*/};
}
Then you get:
public static class MyStaticChild : MyStaticBase<MyChildPlayloadType>
{
public static SomeType AttributeChild;
public static SomeType SomeChildMethod(){/*...*/};
// No need to create the PlayLoad, Load(), and Save().
// You, 'should' be prevented from creating them, more on this in a sec...
}
Usage looks like:
// ...
MyStaticChild.Load(FileNamePath);
MyStaticChild.Save(FileNamePath);
doSomeThing(MyStaticChild.Payload.Attribute);
doSomething(MyStaticChild.AttributeBase);
doSomeThing(MyStaticChild.AttributeChild);
// ...
The person creating the static child does not need to think about the serialization process as long as they understand any limitations that might be placed on the platform's or environment's serialization engine.
Statics (singletons and other forms of 'globals') often come up around configuration storage. Static inheritance would allow this sort of responsibility allocation to be cleanly represented in the syntax to match a hierarchy of configurations. Though, as I showed, there is plenty of potential for massive ambiguity if basic static inheritance concepts are implemented.
I believe the right design choice would be to allow static inheritance with specific limitations:
No override of anything. The child cannot replace the base
attributes, fields, or methods,... Overloading should be ok, as
long as there is a difference in signature allowing the compiler to
sort out child vs base.
Only allow generic static bases, you cannot inherit from a
non-generic static base.
You could still change the same store via a generic reference MyStaticBase<ChildPayload>.SomeBaseField. But you would be discouraged since the generic type would have to be specified. While the child reference would be cleaner: MyStaticChild.SomeBaseField.
I am not a compiler writer so I am not sure if I am missing something about the difficulties of implementing these limitations in a compiler. That said, I am a strong believer that there is an informational space need for limited static inheritance and the basic answer is that you can't because of a poor (or over simple) design choice.
Static classes and class members are used to create data and functions that can be accessed without creating an instance of the class. Static class members can be used to separate data and behavior that is independent of any object identity: the data and functions do not change regardless of what happens to the object. Static classes can be used when there is no data or behavior in the class that depends on object identity.
A class can be declared static, which indicates that it contains only static members. It is not possible to use the new keyword to create instances of a static class. Static classes are loaded automatically by the .NET Framework common language runtime (CLR) when the program or namespace that contains the class is loaded.
Use a static class to contain methods that are not associated with a particular object. For example, it is a common requirement to create a set of methods that do not act on instance data and are not associated to a specific object in your code. You could use a static class to hold those methods.
Following are the main features of a static class:
They only contain static members.
They cannot be instantiated.
They are sealed.
They cannot contain Instance Constructors (C# Programming Guide).
Creating a static class is therefore basically the same as creating a class that contains only static members and a private constructor. A private constructor prevents the class from being instantiated.
The advantage of using a static class is that the compiler can check to make sure that no instance members are accidentally added. The compiler will guarantee that instances of this class cannot be created.
Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object. Static classes cannot contain an instance constructor; however, they can have a static constructor. For more information, see Static Constructors (C# Programming Guide).
When we create a static class that contains only the static members and a private constructor.The only reason is that the static constructor prevent the class from being instantiated for that we can not inherit a static class .The only way to access the member of the static class by using the class name itself.Try to inherit a static class is not a good idea.
I run into the problem when trying to code an IComparer<T> implementation against a third-party library where T is an enum embedded in a class as in the following:
public class TheClass
{
public enum EnumOfInterest
{
}
}
But because the enum is defined within a third-party library class, I can't write the comparer because the following gives a "cannot extends list" error:
public class MyComparer : IComparer<TheClass.EnumOfInterest>
{
}
I'm not even extending a static class -- I'm just implementing a comparer of a enum defined in a class.

Categories

Resources