Decreasing the visibility of base class properties - c#

I had created a base class that has many public properties and were been used perfectly. Now i want to use this class to derive other class , but i do'nt want some of its properties to be exposed outside the derived class that inherits it. Is there any way that the properties of base class that are public cannot be exposed outside its derived class.(The properties that are to be hidden are public because they are used in other classes that inherits it).Any help will be highly appericiated.

You want to make them protected.
From MSDN:
A protected member is accessible within its class and by derived class instances.

I agree with cadrell0 about marking them protected, but just in case you are looking for a solution where the properties are actually public, but hidden to users of a certain derived class, you can use an explicit interface
interface IHaveMethodsYouCanHide { void Foo(); }
class Base : IHaveMethodsYouCanHide { public void Foo() {} }
class NonHidingDerived : Base { }
class HidingDerived : Base, IHaveMethodsYouCanHide
{
void IHaveMethodsYouCanHide.Foo() {}
}
With this code, identifers of type HidingDerived will not allow calls to Foo (unless first cast to IHaveMethodsYouCanHide).

What you're asking for is simply not possible. If type B inherits from type A then it "is-a" type A. B has at least the same accessible contract that type A had. There is no way to hide a public member of A without fundamentally violating this contract.
If you find yourself in a scenario where you want to use A but only expose a subset of the properties then inheritance is not the right solution: containment is the proper solution.
public class B {
private A m_wrapped;
// Expose only the properties you want to expose here
}

Related

Is it possible to restrict a base class to a specific subclass?

I have a need where I would like to have a base class only available to one specific subclass. This is due to a limitation where you cannot define an Attribute as an inner class of a generic.
The reason we want to define the attribute within the generic is when you do that and set its type to protected, that attribute is now only available to subclasses of your base class, keeping your API clean.
As an example, consider the abstract class ExampleMarkupExtension<T> that inherits from MarkupExtension. I want to define the attribute StaticInfoAttribute as an inner class, so it is only available to subclasses of ExampleMarkupExtension<T>.
However, as mentioned, you can't define an attribute as an inner class of a generic, so my workaround is to create a second, non-generic ExampleMarkupExtensionBase class which inherits from MarkupExtension, define StaticInfoAttribute as an inner class there, then have the generic inherit from that class instead.
The issue is now I have an extra class in my hierarchy that anyone can subclass. While it's technically harmless, I like keeping my API surface area clean.
Example
ExampleMarkupExtensionBase : Non-generic abstract base class
This is the class that defines the attribute which should only be available to subclasses of this class. This class only exists because I can't put StaticInfoAttribute within the generic abstract base class ExampleMarkupExtension<T> below.
public abstract class ExampleMarkupExtensionBase : MarkupExtension {
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=false)]
protected class StaticInfoAttribute : Attribute {
public StaticInfoAttribute(string value) => Value = value;
public readonly string Value;
}
}
ExampleMarkupExtension<T> : Generic abstract base class
This is the class that holds the static members which are unique to the subclasses of this class. It does this by using the subclass as the type parameter for the base class (see the where clause). The value of the static field is set from the attribute, hence it only being of any use for this specific subclass of ExampleMarkupExtension above.
public abstract class ExampleMarkupExtension<T> : ExampleMarkupExtensionBase
where T : ExampleMarkupExtension<T> {
static ExampleMarkupExtension() => Value = typeof(T).GetRequiredCustomAttribute<StaticInfoAttribute>().Value;
public static readonly string Value;
public sealed override object ProvideValue(IServiceProvider serviceProvider)
=> Value;
}
Rationale
Some may ask what's the harm of leaving it as-is. Technically, there's nothing wrong with letting a person subclass ExampleMarkupExtensionBase. There's just no point to it.
For that matter, there's technically no harm with moving the StaticInfoAttribute outside of the class as well, removing the need for the non-generic base class entirely. I just chose the former approach as it's more important to restrict the attribute's usage than it is to stop someone from subclassing the base class.
As per our comments, you can use the EditorBrowsable attribute to hide the method from projects that reference it. Note however it just hides it from IntelliSense and if a user was to type out ExampleMarkupExtensionBase that the class still exists and is valid to be used.
[EditorBrowsable(EditorBrowsableState.Never)]
public abstract class ExampleMarkupExtensionBase : MarkupExtension

Why is an Array an abstract class in C#? [duplicate]

The C# spec, section 10.1.1.1, states:
An abstract class is permitted (but
not required) to contain abstract
members.
This allows me to create classes like this:
public abstract class A
{
public void Main()
{
// it's full of logic!
}
}
Or even better:
public abstract class A
{
public virtual void Main() { }
}
public abstract class B : A
{
public override sealed void Main()
{
// it's full of logic!
}
}
This is really a concrete class; it's only abstract in so far as one can't instantiate it. For example, if I wanted to execute the logic in B.Main() I would have to first get an instance of B, which is impossible.
If inheritors don't actually have to provide implementation, then why call it abstract?
Put another way, why does C# allow an abstract class with only concrete members?
I should mention that I am already familiar with the intended functionality of abstract types and members.
Perhaps a good example is a common base class that provides shared properties and perhaps other members for derived classes, but does not represent a concrete object. For example:
public abstract class Pet
{
public string Name{get;set;}
}
public class Dog : Pet
{
public void Bark(){ ... }
}
All pets have names, but a pet itself is an abstract concept. An instance of a pet must be a dog or some other kind of animal.
The difference here is that instead of providing a method that should be overridden by implementors, the base class declares that all pets are composed of at least a Name property.
The idea is to force the implementor to derive from the class as it is intended to provide only a basis for a presumably more specialized implementation. So the base class, while not having any abstract members may only contain core methods an properties that can be used as a basis for extension.
For example:
public abstract class FourLeggedAnimal
{
public void Walk()
{
// most 4 legged animals walk the same (silly example, but it works)
}
public void Chew()
{
}
}
public class Dog : FourLeggedAnimal
{
public void Bark()
{
}
}
public class Cat : FourLeggedAnimal
{
public void Purr()
{
}
}
I think a slightly more accurate representation of your question would be: Why does C# allow an abstract class with only concrete members?
The answer: There's no good reason not to. Perhaps someone out there has some organizational structure where they like to have a noninstantiatable class at the top, even if a class below it just inherits and adds nothing. There's no good reason not to support that.
You said it -- because you can't instantiate it; it is meant to be a template only.
It is not "really a concrete class" if you declare it as abstract. That is available to you as a design choice.
That design choice may have to do with creating entities that are (at risk of mixing the terminology) abstractions of real-world objects, and with readability. You may want to declare parameters of type Car, but don't want objects to be declarable as Car -- you want every object of type Car to be instantiated as a Truck, Sedan, Coupe, or Roadster. The fact that Car doesn't require inheritors to add implementation does not detract from its value as an abstract version of its inheritors that cannot itself be instantiated.
Abstract means providing an abstraction of behaviour. For example Vehicle is an abstract form. It doesn't have any real world instance, but we can say that Vehicle has accelerating behaviour. More specifically Ford Ikon is a vehicle, and Yamaha FZ is a vehicle. Both these have accelerating behaviour.
If you now make this in the class form. Vehicle is abstract class with Acceleration method. While you may/ may not provide any abstract method. But the business need is that Vehicle should not be instantiated. Hence you make it abstract. The other two classes - Ikon and FZ are concrete classes deriving from Vehicle class. These two will have their own properties and behaviours.
With regards to usage, using abstract on a class declaration but having no abstract members is the same as having the class public but using protected on its constructors. Both force the class to be derived in order for it to be instantiated.
However, as far as self-documenting code goes, by marking the class abstract it informs others that this class is never meant to be instantiated on its own, even if it has no virtual or abstract members. Whereas protecting the constructors makes no such assertion.
The compiler does not prevent implementation-logic, but in your case I would simply omit abstract ?! BTW some methods could be implemented with { throw Exception("must inherit"); } and the compiler could not distinguish fully implemented classes and functions including only throw.
Here's a potential reason:
Layer Supertype
It's not uncommon for all the objects
in a layer to have methods you don't
want to have duplicated throughout the
system. You can move all of this
behavior into a common Layer
Supertype.
-- Martin Fowler
There's no reason to prevent having only concrete methods in an abstract class - it's just less common. The Layer Supertype is a case where this might make sense.
I see abstract classes serving two main purposes:
An incomplete class that must be specialized to provide some concrete service. Here, abstract members would be optional. The class would provide some services that the child classes can use and could define abstract members that it uses to provide its service, like in the Template Method Pattern. This type of abstract class is meant to create an inheritance hierarchy.
A class that only provides static utility methods. In this case, abstract members don't make sense at all. C# supports this notion with static classes, they are implicitly abstract and sealed. This can also be achieved with a sealed class with a private constructor.

Inconsistent accessibility: base class is less accessible than class

So I have an abstract base class in a DLL and child classes of that class. I want the childs to be public, but the base to be private so that it cannot be accessed outside of the dll.
How do I do that?
You don't and you can't.
If you want to expose the class as public, the base-type must be public. One other option is to have a public interface, and only expose the type via the interface (presumably with a factory method somewhere for creating instances).
One final option is to encapsulate the base-class rather than inherit it.
Make it public, make all constructors internal (if you're using the default constructor, add a parameterless constructor to override that).
Then while public and not sealed, it can't be sub-classed by external code.
Just to clarify what I was saying in comments on #Marc Gravel's answer you could
public ChildClass : ParentClass
{
}
public ParentClass
{
internal void MethodIdontWantToExpose()
{
}
}
That said an interface is probably the best solution

Can an abstract class contain a public method?

Constructors of an abstract class shouldn't be public and they should be protected. My question is about methods in that abstract class. Can we declare them as public or they should be protected too for the same reason?
The justification for constructors on abstract types being protected is that there is simply no other entity that could call the constructor other than a derived type. Making the constructor public is meaningless in this case as it can't ever be invoked outside the type hierarchy. Hence the recommendation is to use protected as it's the most appropriate access modifier.
The same logic doesn't hold true with other members on the type. They can be freely invoked from outside the type hierarchy should their access modifier permit it.
public abstract class Dog {
// Public is appropriate here as any consumer of Dog could access
// Breed on an instantiated object
public abstract string Breed { get; }
// Public would be meaningless here. It's not legal to say
// 'new Dog' because 'Dog' is abstract. You can only say
// 'new Poodle' or 'new Bulldog'. Only derived types like
// Poodle or Bulldog could invoke the Dog constructor hence it's
// protected
protected Dog() { }
}
public class Poodle : Dog { }
public class Bulldog : Dog { }
Whether or not a particular member should be public or protected is highly dependent upon the particular API. The reasoning should be the exact same for abstract types as it is for non-abstract types
Abstract classes shouldn't have public constructors because they don't make sense. Abstract classes are incomplete, so allowing a public constructor (which anyone could call) wouldn't work as you can't instantiate an instance anyway.
Methods on abstract classes are another story. You can have implementation in an abstract class, which is the behavior that all subclasses will inherit. Think of a Shape class. Its purpose is to draw a shape on the screen, so it makes sense to make a Draw method public as you'll want callers to be able to ask your Shape to draw. The method itself can be abstract, forcing subclasses to implement, or possibly provide an implementation which may or may not allow overriding. It depends on what the defined behavior of your class should be.
It depends on your use case. If you want the methods of the abstract class visible to instances of your derived class, you should make them public. If, on the other hand, you want the methods visible only to your derived class, you should make them protected.

How can I create a class A in C#, where A can only be inherited by B, C, D?

There is some mechanism to allow a class to be inherited by N classes only in C#?
You may put it and it's derived classes in a separate assembly, and declare the constructor of the base class as internal. That way although you could inherit from it in a different assembly, but you wouldn't be able to instantiate any derived class.
No, but you can always make the constructor throw an exception if it exceeds the limit.
// can be inherited only by classes in the same assembly
public abstract class A
{
protected internal A() { }
}
// can't be inherited
public sealed class B : A
{
}
Just for my personal edification, I'd like to know more about the business context which make such a design choice desirable, since my first thougt at reading the title was "Oh, very very bad idea ! A base class is NEVER supposed to know anything (and worse : to rule) its derived classes".
You can make the class A abstarct and inherit it in any number of classes..

Categories