Does declaring a nested class has some functional/hierarchical impact on the objects or is just a matter of access/visibility.
I have 4 classes on my program but I only want to make 1 of them public, originally I declared them as follows:
namespace mynamespace{
private class A{
// some members;
}
private class B{
// some members;
}
private class C{
// some members;
}
public class D{
// some members;
}
}
but the compiler complained, so among other things, I changed private to internal, however opposite to what I thought, all 4 classes are available to external programs, which I don't want. I tried everything I could imagine but no luck, so I thought I should try nesting class A, B and C inside class D, as follows:
namespace mynamespace{
public class D{
// some members;
private class A{
// some members;
}
private class B{
// some members;
}
private class C{
// some members;
}
}
}
...this way only the class I want to publish is actually published, however since I'm new to C# I'm not sure this is the proper way to do it. I worry this change could have consequences related to memory consumption, performance, etc.
If the only thing you're trying to accomplish is to make only one accessible to other projects then you don't need nested classes. Just mark all of the ones you don't want visible to other projects as internal (or just use no modifier as internal is the default).
If you want to hide them from other classes within the same project then using a nested private class will do the trick. Do note that nested classes gain access to the non-public members of the type in which they are nested. Hence they gain a bit of power while at the same time being less accessible to other types
Related
I am trying on a project to use private values in my internal functions. In past I used only public ones, but I noticed that obfuscation is working much better when using as much as possible private parameters.
My question is regarding Parent/Child classes.
In my main class I define all the parameters as following :
public class MyFatherClass
{
private long id = -1;
public long ID { get { return this.id; } set { this.id = value; } }
...
}
So in all internal functions I access to my private value instead of the public one.
Then in my daughter class I just add parameters specific to the child class.
public class MyChildClass : MyFatherClass
{
private long anotherParameter = -1;
public long AnotherParameter { get { return this.anotherParameter; } set { this.anotherParameter = value; } }
...
}
Just, I see that in my Parent class, I can access to id and ID without problem, but from daughter classes I can only access ID(as id is private).
If I understood correct, I would need to replace all private by protected in my parent lass, so it would solve the problem?
What I don't understand is the code is working even if I leave it so.
Why don't I have an error message, when I set ID value in daughter class, the sentence this.id=value is executed, but how can can I access to it from my child class if it is private?
I am now hesitating, may I just add a private id in each child class, or may I set id to protected in my parent class?
Thanks for your explanations.
Edit, just adding a screenshot of my reversed code after obfuscation, so you could understand difference on how are obfuscated private/public methods/fields
Why don't I have an error message, when I set ID value in daughter class, the sentence this.id=value is executed, but how can can I access to it from my child class if it is private?
When you call a public method on a class, that method can access private members of that class:
public class Foo
{
public void Bar()
{
Baz();
}
private void Baz()
{
// private method called by public method
}
}
var foo = new Foo();
foo.Bar();
This compiles just fine. Your setter is the same: it's public, so callable from everywhere, even if it accesses private members.
As for making your field (private long id = -1;) protected: yes, that will mean you can access it in derived classes. But whether you want to is another question.
You have declared a public property for a reason. Perhaps you want to do some validation in its setter or getter. If not, if you're just using a property to access a private field, you could just ditch the entire private field and use an auto-implemented property:
public long ID { get; set; } = -1;
Then you can access the property everywhere, from within itself, from derived classes and from code using this class.
See also:
What is the difference between a field and a property?
What are Automatic Properties in C# and what is their purpose?
Here is a short and reduced description of what access modifiers do:
Public : fields (variables) and properties (variables encapsulation) and methods (functions and procedures) are visible and accessible by the class itslef, by its childs and by any other external classes.
Private : members (fields, properties and methods) are visible and accessible only by the class, not by its childs nor by any external class.
Protected : members are visible and accessible by the class and by its childs, but not by others classes.
Internal : members are visible and accessible by the class and by its childs and by any class that is in the same assembly (.exe and .dll), but not by a class from another assembly.
So you should set id to protected in the parent class to use it in the childs.
But here is the rule:
If childs classes can modify id you should set as a protected field, and offer a public property (get) if available for external items.
If childs classes are not allowed to modify it you should set it private and offer :
A propected property with only a getter if external items can't access it.
A public property with only a getter if external items can access it.
Don't repeat a member with the same name else it will hide the parent and can cause polymorphism problems, else you know what you do.
You can read these tutorials to more understand access modifier keywords:
C# Access Modifiers
Access Modifiers (C# Reference)
Here are some readings:
C# Tutorial Level 0
C# Tutorial Level 1
C# Tutorial Level 2
C# Tutorial Level 3
C# Snippets # Techi.io
Beginning Visual C# 2008 Programming
The MyChildClass class which inherits from the MyFatherClass can not access the id field because it's private. To make it accessible, you will need to change the field's access modifier to either:
protected :
////////////////////////////////////
// Dll1.dll
////////////////////////////////////
namespace Dll1
{
public class Base
{
//The field we are attempting to access
protected int a;
}
public sealed class Main : Base
{
public void DoSomething()
{
//Can be done sins Main inherits from Base
base.a = 100;
}
}
public class Invader
{
public int GetA()
{
var main = new Main();
main.DoSomething();
// can not be done sins the field is only accessible by those that inherit from Base
return main.a;
}
}
}
////////////////////////////////////
// Dll2.dll
////////////////////////////////////
namespace Dll2
{
public class ADll2Class : Dll1.Base
{
public int GetA()
{
//Can be done because ADll2Class inherits from Dll1's Base class
return base.a;
}
}
}
private protected :
Same as protected but, in the example above, Dll2's class, ADll2Class, will not be able to access the a field because it would be privately protected, in other words only classes from the same dll as Base which inherit from Base will be able to access a.
or you can set it to
internal :
If the a field in the example above was internal, then, same as private protected, Dll2's class wont be able to access it but, the Invader class in Dll1 will be able to access it sins it's part of the same dll as Base.
Note that, sins you mentioned obfuscation, try as hard as you will, the id field can still be accessed by others in an obfuscated state with the help of reflection, especially sins you provide a public property ID, might as well set everything in your project to internal.
Apparently this works in Java:
class BigClass
{
public SecretClass not_so_secret = new SecretClass();
public class SecretClass
{
// Methods and stuff
}
}
But is there no equivalent in c#? Where I can create an instance of BigClass but NOT be allowed to create the subclass SecretClass:
class testing_class
{
BigClass BIG_CLASS_SHOULD_BE_ALLOWED = new BigClass();
BigClass.SecretClass SUB_CLASS_SHOULD_NOT = new BigClass.SecretClass();
}
I've tried combinations of internal (which sounded right...), private, protected - basically just all of them now :D
Is it a fundamental no-way-round principle in c# to always have this one-way street for access modifiers?
By the way I did find a sort-of answer here referring to Kotlin (whatever that is) and it seems to be a strict thing that just wouldn't make sense to some or be dangerous for some reason - public instances of an "internally" created private class
Is there no way to achieve that level of access in c#?
If you want to make a member (field, property, method, event, delegate or nested type) public, all the types exposed by this member must be public.
However, there is a trick on how you can make the class only instantiateable within BigClass: Make the class abstract, and if you need to write a constructor, make it protected or, since C# 7.2 private protected (see below). Then derive a nested private class from it.
public class BigClass
{
public SecretClass not_so_secret = new VerySecretClass();
public abstract class SecretClass
{
}
private class VerySecretClass : SecretClass
{
}
}
Also make everything private or protected that you don't need to expose. You can even give the setters more restrictive access modifiers.
public string Text { get; private set; } // or: protected set;
It also helps to make things internal if you are writing a class library. It makes things invisible for other assemblies.
Since C# 7.2 there is also a new level of accessibility (from C# 7 Series, Part 5: Private Protected):
Private Protected
Private Protected: The member declared with this accessibility can be visible within the types derived from this containing type within
the containing assembly. It is not visible to any types not derived
from the containing type, or outside of the containing assembly. i.e.,
the access is limited to derived types within the containing assembly.
Sounds like silly idea but I was wondering if it's possible somehow.
Is it possible to change the base class of a derived class at runtime? Of course, there are lot of ifs and buts and the the question of why would someone do it and its a bad design probably and all that.
Keeping all those aside (even though they might be perfectly valid), let's say, just for kicks or to show your nerdiness, is it possible in C# or any language for that matter?
So something like:
public class baseOriginal {
public string justAProperty;
}
public class baseSwapped {
public int sillyNumber;
}
public class derivedClass : baseOriginal {
public bool iAmDumb;
}
void Main() {
baseOriginal derived = new derivedClass ();
Console.WriteLine(derived.justAProperty);
baseSwapped derivedSwapped = (??);
Console.WriteLine(derivedSwapped.sillyNumber);
}
It isn't possible in C#. Probably what you want is more of a prototype-based solution commonly found in dynamic languages like JavaScript where you can "extend" the functionality of the object by adding to how it's defined.
But to accomplish what your code hints at doing, you can have the swappable classes inherit from a common ancestor class. That way you can assign instances of each to their decendents.
public class baseClassAncestor{
}
public class baseOriginal:baseClassAncestor {
public string justAProperty;
}
public class baseSwapped:baseClassAncestor {
public int sillyNumber;
}
public class derivedClass : baseOriginal {
public bool iAmDumb;
}
You can do one time base class swap by loading different assemblies that implement base class BEFORE using derived class. But this approach will not make your exact code working as you will not be able to compile that - but moving access to methods of different base classes to separate functions could be made working.
You add UnionBase class that contains all possible methods/properties from all base classes so you can compile your Main code against the assembly with this class. Than at run time you load assembly that has contains your particular base class.
Usual warning: You need to have very good reasons and understanding for going this route. I.e. existing external code is a reason to consider such approach.
"Don't do it at home, performed on a closed course by trained professional".
One more possible workaround could be implemented using some AOP solution that is based on compile-time weaving, i.e. PostSharp, which is able to seamlessly inject new methods and interfaces to existing types as well as modify (intercept) existing ones.
There is actually a good reason where you may want to swap the base class. Let say you want to modify the base class but you don't wan't to perturb the current code base as it is shared among other teams. Let say there are 10+ derived class that inherits from base. You could create 10+ custom derived classes to override the base class but that is a lot of work. Here is what you do. The key to the problem is to create an interface and a base proxy class.
class Program
{
static void Main(string[] args)
{
IActionable action = new Derived<Base1>();
action.open();
action = new Derived<Base2>();
action.open();
}
}
// Proxybase is a fake base class. ProxyBase will point to a real base1 or
// base2
public class Derived<T>:ProxyBase,IActionable
{
public Derived():base(typeof(T))
// the open function is not overriden in this case allowing
// the base implementation to be used
}
// this looks like the real base class but it is a fake
// The proxy simply points to the implementation of base1 or base2 instead
public abstract class ProxyBase: IActionable
{
IActionable obj;
public ProxyBase(Type type,params object[] args)
{
obj = (IActionable)Activator.CreateInstance(type,args);
}
public virtual void open()
{
obj.open();
}
}
// notice base1 and base2 are NOT abstract in this case
// consider this the original implementation of the base class
public class Base1: IActionable
{
public virtual void open()
{
Console.WriteLine("base1 open");
}
}
// here base2 acquired the functionality of base1 and hides base1's open
function
// consider this implementation the new one to replace the original one
public class Base2: Base1, IActionable
{
public new virtual void open()
{
Console.WriteLine("base2 open");
}
}
public interface IActionable
{
void open();
}
The result would be as follows
base1 open
base2 open
UPDATE:
Although this answer works, the reality is that inheritance introduces coupling which makes this exercise difficult at best. Also, in a practical scenario, your requirements may lead you to want to derive from multiple base class which is not possible in c#. If you want to interchange the base class you are best to use the bridge design pattern (which in fact avoids inheritance altogether thus avoiding the coupling).
The closest thing I can think of is the following:
http://msdn.microsoft.com/en-us/library/dd264736.aspx
static void Main(string[] args)
{
ExampleClass ec = new ExampleClass();
// The following line causes a compiler error if exampleMethod1 has only
// one parameter.
//ec.exampleMethod1(10, 4);
dynamic dynamic_ec = new ExampleClass();
// The following line is not identified as an error by the
// compiler, but it causes a run-time exception.
dynamic_ec.exampleMethod1(10, 4);
// The following calls also do not cause compiler errors, whether
// appropriate methods exist or not.
dynamic_ec.someMethod("some argument", 7, null);
dynamic_ec.nonexistentMethod();
}
class ExampleClass
{
public ExampleClass() { }
public ExampleClass(int v) { }
public void exampleMethod1(int i) { }
public void exampleMethod2(string str) { }
}
I have no idea if the dynamic language runtime can do what you want it to do.
Closest you could get would be to
derive from both types by defining at
least one as an interface, then
casting derived from one to the other.
I would have to agree, based on the example this suggestion would satisfy what he wants to do, it also is a better design then what he actually wants to do.
Closest you could get would be to derive from both types by defining at least one as an interface, then casting derived from one to the other.
In C#, a superclass's static members are "inherited" into the subclasses scope. For instance:
class A { public static int M() { return 1; } }
class B : A {}
class C : A { public new static int M() { return 2; } }
[...]
A.M(); //returns 1
B.M(); //returns 1 - this is equivalent to A.M()
C.M(); //returns 2 - this is not equivalent to A.M()
Now, you can't inherit static classes, and the only place I can imagine that static inheritance might matter ignores it entirely: although you can make a generic constraint that requires a type parameter T to be a subclass of A, you still cannot call T.M() (which probably simplifies things for the VM), let alone write a different M implementation in a subclass and use that.
So, the "inheritance" of static members merely looks like namespace pollution; even if you explicitly qualify the name (i.e. B.M) A's version is still resolved.
Edit compare with namespaces:
namespace N1{ class X(); }
namespace N1.N2 { class X(); }
namespace N1.N2.N3 { [...] }
Within N1.N2.N3 It makes sense that if I use X without qualification it refers to N1.N2.X. But if I explicitly refer to N1.N2.N3.X - and no such class exists - I don't expect it to find N2's version; and indeed to compiler reports an error if you try this. By contrast, if I explicitly refer to B.M(), why doesn't the compiler report an error? After all, there's no "M" method in "B"...
What purpose does this inheritance have? Can this feature be used constructively somehow?
So, the "inheritance" of static
members merely looks like namespace
pollution
That's right, except that one guy's pollution is another guy's added spicy flavouring.
I think Martin Fowler, in his work on DSLs, has suggested using inheritance in this way to allow convenient access to static methods, allowing those methods to be used without class name qualification. So the calling code has to be in a class that inherits the class in which the methods are defined. (I think it's a rotten idea.)
In my opinion, static members should not be mixed into a class with a non-static purpose, and the issue you raise here is part of the reason why it's important not to mix them.
Hiding private static mutable data inside the implementation of an otherwise "instancey" class is particularly horrible. But then there are static methods, which are even worse mixers. Here's a typical use of static methods mixed into a class:
public class Thing
{
// typical per-instance stuff
int _member1;
protected virtual void Foo() { ... }
public void Bar() { ... }
// factory method
public static Thing Make()
{
return new Thing();
}
}
It's the static factory method pattern. It's pointless most of the time, but even worse is that now we have this:
public class AnotherThing : Thing { }
This now has a static Make method which returns a Thing, not a AnotherThing.
This kind of mismatch strongly implies that anything with static methods should be sealed. Static members fail to integrate well with inheritance. It makes no sense to have them heritable. So I keep static things in separate static classes, and I gripe about redundantly having to declare every member static when I've already said that the class is static.
But it's just one of those too-late-now things. All real, working languages (and libraries, and products) have a few of them. C# has remarkably few.
I rather have access to all my based static members in derived classes.
Otherwise i would need to know exactly where the static member was defined and call it explicitly.
When using Intellisense you can automatically know every static member available to that kind of class.
Of course, they are not inherited, it's just a shortcut
That's how it works, would probably just be a stupid answer in most cases. But in this case, it is how it works; since you derive from A you say that you are A + the extra features you add.
Therefore you need to be able to access the same variables that you would through an instance of A.
However, inheriting a static class makes no sense while access to the static members / fields / methods does.
An example of this is the following:
internal class BaseUser
{
public static string DefaultUserPool { get; set; }
}
internal class User : BaseUser
{
public int Id { get; set; }
public string Name { get; set; }
public User Parent { get; set; }
}
Where the test looks like this:
User.DefaultUserPool = "Test";
BaseUser.DefaultUserPool = "Second Test";
Console.WriteLine(User.DefaultUserPool);
Console.WriteLine(BaseUser.DefaultUserPool);
Both of the WriteLines outputs "Second Test", this is because both BaseUser and User should use DefaultUserPool, by design. And overriding static implemented methods wouldn't make mucn sense since it's just an accessor in the child-class.
There can be only one. Overriding it would mean that there's a new implementation for that sub-class, which would kill the term "static".
Actually, as I understand it, this is just a shortcut provided by the compiler. Syntax sugar. B.M() will just compile to A.M() since B does not have a static M() and A does. It's for easier writing, nothing else. There is no "static inheritance".
Added: And the requirement for new when "redefining" is just so that you don't accidentally shoot yourself in the foot.
I think it's for accessing protected static members of the base class.
class Base
{
protected static void Helper(string s)
{
Console.WriteLine(s);
}
}
class Subclass : Base
{
public void Run()
{
Helper("From the subclass");
}
}
So... What's the alternative?
The question mentions...
why doesn't the compiler report an error? After all, there's no "M" method in "B"...
But there is a derived "M" method in "B" class.
If the compiler did not present the programmer a unified virtual table for base cases, then the programmer would have to go hunting through base types to find static methods. This would break polymorphism.
Wikipedia...
Subtype polymorphism, almost universally called just polymorphism in the context of object-oriented programming, is the ability of one type, A, to appear as and be used like another type, B....
In strongly typed languages, polymorphism usually means that type A somehow derives from type B, or type C implements an interface that represents type B.
I always see it a means of preventing any form of polymorphism by the inheriting class on those items that you wish to retain the same function for all child classes.
ignore the above for some reason I was thinking of sealed instead of static
I suppose that you'd use static member variables and functions in order to ensure that any data or functionallity is not dependent on the a class instance as it would be instantiated only the once.
An example of use would be say a counter value that would keep a live count of all instances of a superclass's subclasses (each subclass increments the static count value on construction). This count value would be available and equal for all instances of the subclass.
This question already has answers here:
Why/when should you use nested classes in .net? Or shouldn't you?
(14 answers)
Closed 10 years ago.
I'm trying to understand about nested classes in C#. I understand that a nested class is a class that is defined within another class, what I don't get is why I would ever need to do this.
A pattern that I particularly like is to combine nested classes with the factory pattern:
public abstract class BankAccount
{
private BankAccount() {} // prevent third-party subclassing.
private sealed class SavingsAccount : BankAccount { ... }
private sealed class ChequingAccount : BankAccount { ... }
public static BankAccount MakeSavingAccount() { ... }
public static BankAccount MakeChequingAccount() { ... }
}
By nesting the classes like this, I make it impossible for third parties to create their own subclasses. I have complete control over all the code that runs in any bankaccount object. And all my subclasses can share implementation details via the base class.
The purpose is typically just to restrict the scope of the nested class. Nested classes compared to normal classes have the additional possibility of the private modifier (as well as protected of course).
Basically, if you only need to use this class from within the "parent" class (in terms of scope), then it is usually appropiate to define it as a nested class. If this class might need to be used from without the assembly/library, then it is usually more convenient to the user to define it as a separate (sibling) class, whether or not there is any conceptual relationship between the two classes. Even though it is technically possible to create a public class nested within a public parent class, this is in my opinion rarely an appropiate thing to implement.
A nested class can have private, protected and protected internal access modifiers along with public and internal.
For example, you are implementing the GetEnumerator() method that returns an IEnumerator<T> object. The consumers wouldn't care about the actual type of the object. All they know about it is that it implements that interface. The class you want to return doesn't have any direct use. You can declare that class as a private nested class and return an instance of it (this is actually how the C# compiler implements iterators):
class MyUselessList : IEnumerable<int> {
// ...
private List<int> internalList;
private class UselessListEnumerator : IEnumerator<int> {
private MyUselessList obj;
public UselessListEnumerator(MyUselessList o) {
obj = o;
}
private int currentIndex = -1;
public int Current {
get { return obj.internalList[currentIndex]; }
}
public bool MoveNext() {
return ++currentIndex < obj.internalList.Count;
}
}
public IEnumerator<int> GetEnumerator() {
return new UselessListEnumerator(this);
}
}
what I don't get is why I would ever need to do this
I think you never need to do this. Given a nested class like this ...
class A
{
//B is used to help implement A
class B
{
...etc...
}
...etc...
}
... you can always move the inner/nested class to global scope, like this ...
class A
{
...etc...
}
//B is used to help implement A
class B
{
...etc...
}
However, when B is only used to help implement A, then making B an inner/nested class has two advantages:
It doesn't pollute the global scope (e.g. client code which can see A doesn't know that the B class even exists)
The methods of B implicitly have access to private members of A; whereas if B weren't nested inside A, B wouldn't be able to access members of A unless those members were internal or public; but then making those members internal or public would expose them to other classes too (not just B); so instead, keep those methods of A private and let B access them by declaring B as a nested class. If you know C++, this is like saying that in C# all nested classes are automatically a 'friend' of the class in which they're contained (and, that declaring a class as nested is the only way to declare friendship in C#, since C# doesn't have a friend keyword).
When I say that B can access private members of A, that's assuming that B has a reference to A; which it often does, since nested classes are often declared like this ...
class A
{
//used to help implement A
class B
{
A m_a;
internal B(A a) { m_a = a; }
...methods of B can access private members of the m_a instance...
}
...etc...
}
... and constructed from a method of A using code like this ...
//create an instance of B, whose implementation can access members of self
B b = new B(this);
You can see an example in Mehrdad's reply.
There is good uses of public nested members too...
Nested classes have access to the private members of the outer class. So a scenario where this is the right way would be when creating a Comparer (ie. implementing the IComparer interface).
In this example, the FirstNameComparer has access to the private _firstName member, which it wouldn't if the class was a separate class...
public class Person
{
private string _firstName;
private string _lastName;
private DateTime _birthday;
//...
public class FirstNameComparer : IComparer<Person>
{
public int Compare(Person x, Person y)
{
return x._firstName.CompareTo(y._firstName);
}
}
}
There are times when it's useful to implement an interface that will be returned from within the class, but the implementation of that interface should be completely hidden from the outside world.
As an example - prior to the addition of yield to C#, one way to implement enumerators was to put the implementation of the enumerator as a private class within a collection. This would provide easy access to the members of the collection, but the outside world would not need/see the details of how this is implemented.
Nested classes are very useful for implementing internal details that should not be exposed. If you use Reflector to check classes like Dictionary<Tkey,TValue> or Hashtable you'll find some examples.
Maybe this is a good example of when to use nested classes?
// ORIGINAL
class ImageCacheSettings { }
class ImageCacheEntry { }
class ImageCache
{
ImageCacheSettings mSettings;
List<ImageCacheEntry> mEntries;
}
And:
// REFACTORED
class ImageCache
{
Settings mSettings;
List<Entry> mEntries;
class Settings {}
class Entry {}
}
PS: I've not taken into account which access modifiers should be applied (private, protected, public, internal)