This question already has answers here:
method without access modifier
(8 answers)
Default Class Accessibility in C#
(4 answers)
Closed 8 years ago.
If we do not specify Public/Private/Protected, what will it be?
Is there something known as a private class?
1: that depends on whether the class is nested or not. A top level class defaults to internal. A nested class defaults to private.
class TopLevelClass {
class PrivateClass {
}
}
2: yes, but only for nested classes:
class TopLevelClass {
private class ExplicitlyPrivateClass {
}
class ImplicitlyPrivateClass {
}
}
If you don't specify Public/Private/Protected for a main class it will be internal, for a nested class the default access specifier will be private.
private class exists. You can access a private class only if it is declared inside another class. Means it is private to the parent class as
class example //which is default interal
{
private class ex
{
}
class ex1 //default private
{
}
}
1) If no modifier is specified, the visibility will depend on the situation where it is omitted; the topic is discussed in this question.
2) In the following code, InnerClass is private in OuterClass.
namespace ClassTest
{
class OuterClass
{
private class InnerClass
{
}
OuterClass()
{
InnerClass Test = new InnerClass();
}
}
class Program
{
static void Main(string[] args)
{
OuterClass TestOne = new OuterClass();
InnerClass TestTwo = new InnerClass(); // does not compile
}
}
}
What are the Default Access Modifiers in C#?
and there is a private class but in my opinion its pointless
Related
This question already has answers here:
When and why would you seal a class?
(5 answers)
Closed 2 years ago.
I know that you can not inherit from a class once sealed is used but I am confused what is the difference between these two: private and sealed?
Can't we make the base class members private if we don't want to inherit them instead of the whole class? What is the point of using sealed class?
private: private limits the visiblity to a scope. Declaring a private class within a class means that sub-class can't be seen from outside of the class.
This is also true for methods and properties - they can be seen within the class, but not to any consumers or inheritors.
private keyword is used for declaring class.
sealed: If a class is declared as sealed, that means that you cannot inherit from the class. sealed class can be used when a class is internal to the operation of the library, class or why you do not want that class to be overridden because it may affect the functionality.
sealed keyword is used for declaring class
example
public class Parent {
// some thing at here
private readonly SubClass sc;
// ctor
public Parent () {
sc = new SubClass();
}
public string foo () {
return sc.bar();
}
private class SubClass {
// have some thing here
public string bar() {
//..............
return "...........";
}
}
}
You need to understand difference between inheritability and accessibility.
If you want to make your class non-inheritable, making it sealed is the best option. Also a class can not be protected, private or internal protected. Only sub class can have those access specifiers. A normal class which is directly under a namespace can only be public or internal.
Now coming to you point of making all the members private in the base class. Doing that does not serve any purpose.
You inherit a class only to reuse certain properties and/or method or override them in the inherited class. If you make all the members private in the base class you won't be able access them outside even using the object of base class.
Then what's the point of having them in the base class.
public class MyClass
{
private void MyMethod() //You can not inherit this method but you can not use it using 'MyClass' also.
{
//Some code.
}
}
MyClass myObj = new MyClass();
myObj.MyMethod(); // You can not do this as the method is private.
Now if you inherit this class in another class
public ChildClass : MyClass
{
public void ChildMethod()
{
// Some Logic
}
}
Now when you do
MyClass obj = new ChildClass();
You can not do
obj.MyMethod(); //coz this is private method.
You can not do following too.
obj.ChildMethod(); //coz that method is not known to MyClass.
So if you are making members private just for the sake of making them not available for inheritance, you are losing their accessibility from the base class too.
Understood your confusion,
First of all there is no independent private class inside a namespace, compiler throws an error.
If you make a method void m1() private inside public class A, then the method m1 is not accessible from public class B.
Sealed classes are accessible to other classes though it stops inheritance, meaning you cannot use it to derive from.
In the example below, you wont be able to access the method privatemethod from the Main(), but sealed class and sealed method can be accessed. So sealed can be accessed though cannot be inherited, that's the difference.
namespace ConsoleApp1
{
using System;
public class A
{
public virtual void test()
{
Console.WriteLine("Class A");
}
}
public class C
{
public void testSealFromOutsideClass()
{
B instanceB = new B();
instanceB.test();
}
}
public sealed class B : A
{
public override void test()
{
Console.WriteLine("Class B");
}
private void Privatemethod()
{
Console.WriteLine("Printing from a private method");
}
}
//public class C : B {}
public class TestSealedClass
{
public static void Main()
{
A a = new B();
a.test();
C c = new C();
c.testSealFromOutsideClass();
B b = new B();
Console.Read();
}
}
}
This question already has answers here:
In C#, what is the difference between public, private, protected, and having no access modifier?
(19 answers)
Closed 6 years ago.
Suppose I have a base class:
public class A {
public float someValue;
<Access Modifier Here> float SomeValue {
get {
return someValue;
}
}
}
And I want to derive from it:
public class B : A {
public float SomeProperty {
get {
return SomeValue;
}
}
}
What access modifier would I use if I want to make the SomeValue property only available to the deriving class and not anywhere else?
for only derived classes.. use protected
Protected means that access is limited to the containing class or types derived from the containing class.
This question already has answers here:
How to make a property protected AND internal in C#?
(8 answers)
Closed 7 years ago.
Consider the following classes:
public class Vehicle { ... }
public class Coverage { ... }
public class VehicleList : IEnumerable<Vehicle> { ... }
public class CoverageList : IEnumerable<Coverage> { ... }
public abstract class Quote
{
protected VehicleList vehicles;
protected CoverageList coverages;
internal Quote() { ... }
public IReadOnlyCollection<Vehicle> Vehicles
{
get { return this.vehicles.AsReadOnly(); }
}
public IReadOnlyCollection<Coverage> Coverages
{
get { return this.coverages.AsReadOnly(); }
}
...
}
public sealed class OhQuote : Quote
{
//needs to access protected fields
...
}
public sealed class InQuote : Quote { ... }
public sealed class MiQuote : Quote { ... }
Quote fully encapsulates the functionality of both VehicleList and CoverageList so I'd like to mark those classes as internal. The problem is that they are the types of protected fields of a public class. If I mark those fields as protected internal then they are protected OR internal. What I really need is for them to be protected AND internal (with protected taking precedence within the assembly). You can see that neither Quote (which has an internal constructor) nor its subclasses (which are sealed) can be extended outside the assembly. I've already figured out how to achieve the desired functionality using public interfaces but wanted to make sure there's not a more concise way.
Although the .NET runtime supports this concept ("FamilyAndAssembly"), C# currently does not.
This was proposed for C# 6.0 in the form of the private protected access modifier, but the feature was dropped.
UPDATE: private protected was added to C# 7.2.
As an addendum:
If you want not to use interfaces and -as you see- there is no C# support to achieve that goal, remember: you can always use reflection to do very weird and strange things like that.
You can set the field to private and using reflection you can assign new values from wherever you want, for sure from derived classes in same assembly.
I question the need for your derived classes to access Quote's fields directly.
I am asking if there is a way to achieve the desired functionality without using public interfaces.
I think you can safely change the modifiers on the fields to private and have the derived classes manipulate the fields indirectly through protected methods defined in your Quote base class. No additional public interfaces would be required.
Here is an example of what it could look like:
public class Vehicle {}
public class Coverage {}
// Set these as "internal" as you were hoping for...
internal class VehicleList : IEnumerable<Vehicle>
{
public void Foo() {}
}
internal class CoverageList : IEnumerable<Coverage>
{
public void Bar() {}
}
public abstract class Quote
{
// Mark these as "private"
private VehicleList vehicles;
private CoverageList coverages;
internal Quote() {}
public IReadOnlyCollection<Vehicle> Vehicles
{
get { return this.vehicles.AsReadOnly(); }
}
public IReadOnlyCollection<Coverage> Coverages
{
get { return this.coverages.AsReadOnly(); }
}
// Add protected methods to manipulate the private fields.
protected void PerformFooOnVehicles()
{
this.vehicles.Foo();
}
protected void PerformBarOnCoverages()
{
this.coverages.Bar();
}
}
public sealed class OhQuote : Quote
{
// We now have indirect access to Quote's private fields.
public void Baz()
{
this.PerformBarOnCoverages();
this.PerformFooOnVehicles();
}
}
public sealed class InQuote : Quote {}
public sealed class MiQuote : Quote {}
This alternative accomplishes the goal of indirectly exposing VehicleList and CoverageList only to derived classes that are part of the same assembly.
This question already has answers here:
Enum "Inheritance"
(17 answers)
Closed 7 years ago.
Is there a way to interface with or inherit the enum of another class? Obviously I can move the enum outside of the class, but I am curious if a reference can be made:
public class deferment
{
public enum test
{
test = 0,
live
}
}
public class defermentLog
{
public enum test1 : deferment:test //this is where I want to reference
{
}
public test1 action()
{
return test1.live;
}
}
In that case, yes, you can.
namespace ConsoleTests
{
using TestAlias = Class1.test;
public class Class1
{
public enum test
{
test,
live
}
}
public class Class2
{
public void x()
{
TestAlias t = TestAlias.live;
}
}
}
Its called a type alias, and its defined like this: using TestAlias= Class1.test;
It should be noted though that you have to define that alias in the file that you use it and it does not copy over to other files, so you have to define it in every one you use it.
This question already has answers here:
What is the best way to define a static property which is defined once per sub-class?
(3 answers)
Having separate copy of base class static member in each derived class
(3 answers)
Closed 9 years ago.
When I write:
public class A
{
public static int v;
}
public class B : A { }
public class C : A { }
Values of A.v, B.v and C.v are all same.
How can I make them to store different static values?
Values of A.v, B.v and C.v are all same.
How can I make them to store different static values?
You can't; A.v, B.v and C.v all refer to the same static field, so they can't have different values.
A possible workaround would be to redeclare v in B and C:
public class A
{
public static int v;
}
public class B : A
{
public static new int v;
}
public class C : A
{
public static new int v;
}
If you do that, A.v, B.v and C.v will effectively refer to different fields, so they can have different values.
(Note the new modifier; it tells the compiler that you're intentionally hiding the member from the base class)
Depending on your exact needs, faester's solution might be better.
Dont make them static but use a virtual readonly property to obtain the same effect:
public class A
{
public virtual int v { get { return 1; } }
}
public class B : A { }
public class C : A
{
public override int v
{
get { return 2; }
}
}