Accesing class methods/variables from another class - c#

stupid question really, I have private variables, which I encapsulated and now I want to access them from another class.
I also have a list in one class and want a lot of classes to access that list (list of objects called fields) (creating a simple farm simulator).
So how can I access them from another class?
I know I can make an instace of a class, but with lists, will that mean that my list won't be the same when I create instances of the class in the classes that I want to access the list in?
I don't think I can use Namespace.class.Something since their not static, or can I?
Maybe use inheritance for list or is that not going to work?
Please help, realllyyy would appreciate any help!!
*thank you in advance

You cannot access a private member from within another class (except the member is a member of a nested class). So the proposal from Konrad Kokosa to use Properties instead was absolutely fine as they should be used to control access from outside the actual class. Having said this you may either turn the access-modifier for that property to public or derive from that class (however, you have to use protected access for the property then).
MyClass {
public static List<Field> MyList {get;set;}
}
AnotherClass {
AnotherClass() {
MyClass.MyList = // whatever
// or also possible
MyClass.MyList.Add(/*new Item*/);
}
}

Private members cannot be used outside of the class (unless you use reflection, which I would not recommend). If you want the members to be available to outside classes, you have to make them "public". If you want your members to be available to all derived classes only, use "protected".

If you want to access the same list from all o the other classes, you should declare it as static:
private static List<Field> s_fields = new List<Field>();
public static List<Field> Fields { get { return s_fields; } }

Related

How to make a derived class inside that class not able to access private members?

class A
{
private int aa = 1;
}
class B : A
{
private int bb = 5;
void DoStuff()
{
aa = bb; //Error, as it should
}
}
Versus:
class A
{
private int aa = 1;
class B : A
{
private int bb = 5;
void DoStuff()
{
aa = bb; //Not an error, bummer
}
}
}
Same stuff, just organized differently. I'm using the second method of organizing my classes because it looks so much cleaner to inherit inside of the class for what I'm doing. My problem is that, in the example above, I don't want A's private members to be accessable to B even though it is inside A. I'm beginning to understand that's the point of doing that systematically, but am I really forced to keep them separate if I want A's private members to be private from B?
Yes, you're really forced to keep the declarations separate if you don't want B to access A's private members because nested classes have access to their containing classes private members.
You can't do that.
A nested class is a class member, just like a method. All class members can see other members, even private. Just as you can see private fields from a method.
If you want to do that, it probably means your nested class shouldn't be nested in the first place.
am I really forced to keep them separate if I want A's private members to be private from B?
Yes. from the documentation
A nested type has access to all of the members that are accessible to its containing type. It can access private and protected members of the containing type, including any inherited protected members.
Also why does it matter? Since you control what goes in B, if you don't want B to use anything from A then don't use it.
All of the other answers here are correct in mentioning that you cannot accomplish what you are trying to do, if you nest your classes rather than use separate declarations and inheritance.
One thing you should examine is the true design behind what you're doing and let that guide what design method you choose.
If you don't intend for any outside class to access Class B and its functionality is strictly required within Class A, then there is no way to (and no real need to) hide the members of A from B because B in this case is actually a member of A, with the same access privileges as say a method within that class.
If you plan to expose this class to other potential classes, then it's matter of design (not a matter of code cleanliness/organization) that should draw you to the first method and keep the declarations separate.

If two class inherit an static field, will the objects of those classes share the same value?

Is it possible that different objects of different classes can use one shared item among themselves (e.g for providing some information on the fly) or better a means of communication between different objects of two different classes ?
Class Base
{
public static string SomeThing = "Shared With All";
}
Class Der1 :Base
{
public void DoSomeThing()
{
SomeThing = "SomeThing Goes in here...";
}
}
Class Der2 :Base
{
public void DoSomeThingElse()
{
Console.WriteLine"(SomeThing);
}
}
....
{
Der1 dr1 = new Der1();
dr1.DoSomeThing();
Der2 dr2 = new Der2();
dr2.DoSomeThingElse(); //shows 'SomeThing Goes in here...'
}
If it helps more, I am trying to create a designer of some kind and so I need to get track of all controls and their associations on the designer. Actually there are only two objects at the moment (one called transaction and the other is called place, different places can be associated with different transactions, and this association is done by the user clicking on one place and pointing to the other transactions (have you seen Proteus? something like that).
So this approach will help me know which object is referring which other object and thus and association between the two can be easily spotted and saved.
The static field isn't really inherited in the same way as normal fields are. There's still just one static field, Base.SomeThing. Both of your derived classes are referring to the same field: if anything changes Base.SomeThing, everything that accesses that field will see the change.
Yep, you've invented a global variable :) It is also almost always a sign of bad design. Try solving your task differently.
It is possible, but think carefully about communicating in this way inside the class. There is no good way to account for concurrency issues and very hard to debug if the value is set multiple places.
You can either use static var's or share stuff using setter and getter. These are basic operators in OOP.
A static field belongs to the class that declares it. Any subclasses of that class gets access to that one static field.
There are some caveats here. Declaring a static variable on a Generic class means that one copy of that variable exists for each closed type of that generic. Here's an example to clarify
public class StaticGenericTest<T>
{
private static int count=0;
public StaticGenericTest()
{
count++;
}
}
If you instantiate a StaticGenericTest<int> and a StaticGenericTest<string> they would have different values for count. However a subclass of StaticGenericTest<int> would share count with all other subclasses of StaticGenericTest<int>.
Also you'll get funny behavior using the ThreadStatic attribute (because you'll get one copy of count per thread) and/or static constructors.
As someone mentioned, Static fields are global state and should be protected as such and used with caution.

Does having a public field with private accessors make sense?

I have a class called GestorePersonale which holds a list of instances of another class:
public List<Dipendente> Dipendenti
{
get;
private set;
}
I want to keep this list modifiable only from the methods the class exposes, and not directly. I noticed that with the code above, one could just do var gp = new GestorePersonale();
gp.Dipendenti.Add( new Dipendente( ... ) );
and be able to perform any other kind of action on the List<Dipendente> itself.
I considered converting the first code snippet to
private List dipendenti;
but I could find a few downsides to that:
This would break the personal rule of mine to try to always use the public fields over the private ones from inside the class's methods whenever possible (even though I'm not sure if it is good practice to do so, so any clarification would be welcome);This would impair any external entities' ability to access the contents of the list for reading purposes only, like, say, to execute a LINQ query over the contents of the list.
What would be the best way to solve this situation?
You can wrap the list in a ReadOnlyCollection<T> and expose that:
private List<Dipendente> dipendenti;
private ReadOnlyCollection<Dipendente> readOnlyDipendenti;
public GestorePersonale()
{
dipendenti = new List<Dipendente>();
readOnlyDipendenti = new ReadOnlyCollection<Dipendente>(dipendenti);
}
public ReadOnlyCollection<Dipendente> Dipendenti
{
get { return readOnlyDipendenti; }
}
Internally, you have access to dipendenti and can add/remove items. External entities have access only to the ReadOnlyCollection<T> that wraps the list, so they can only read, but not add/remove items.
I would agree with dtb that ReadOnlyCollections is the way to go. However, you can return it from the property getter (using AsReadOnly) and drop the method.
private List<Dipendente> dipendenti = new List<Dipendente>();
public ReadOnlyCollection<Dipendente> ReadOnlyDipendenti
{
get
{
return dipendenti.AsReadOnly();
}
}
there are a couple of things you can do:
you use ReadOnlyCollection
you can return an IEnumerable<_type>
you can wrap the list in another class
you can roll your own collection class, implementing the appropriate interface
the method you use depends on the functionality you need and what you want/need to expose to the user of your class
What you have is a public property with a private accessor. It is very useful. It allows an instance to expose a value that is controlled (set) by the instance itself, e.g. a state.
For example, take a collection with a Count property. It makes no sense for it have a public accessor. An implementation could be to update the property (internally) when the collection is changed (to avoid having to count it each time).
Do a setter method or wrap the field in another class. This is a classic collection set and collection.add problem.

public inner classes

Can anyone explain, why we can do such thing and why we need this
public class OuterClass
{
public class InnerClass
{
}
}
Why we need public inner whatever: struct, class, enum or static class?
I think that if it is inner then it must be only private or protected.
You don't generally need public nested types - but they can be useful sometimes. They make it very clear that one type is explicitly associated with another.
They also allow the nested type to access the private members of the enclosing type (in C#), which may be useful at times. I would guess that List<T>.Enumerator may do that, for example. In Java the access rules work the other way round - the enclosing class has access to the private members of the nested classes.
I think would have to explain why you'd want to explicitly prohibit this rather than why it's needed, as such. I can't think of anywhere else that you can specify an access modifier but can't make it public, other than for inconsistency (declaring a public method with an internal return type, for example).
Public inner types are generally not recommended, see this reference
http://msdn.microsoft.com/en-us/library/tdz1bea9(v=VS.71).aspx
...but since there are (may be) exceptions, this is still allowed
Consider this example:
public class TrainingFile {
public List<TrainingFileEntry> getEntries() {
return ...
}
public class TrainingFileEntry {
int x;
int y;
}
}
You want to hide the details of the TrainingFileEntry, but your customer needs to be able to use it. Ofc you could create an own file for this nested class, but such a nested helper class ist mostly not a "standalone" and stuck to the class where it is nested. -)
Its very useful when every member of InnerClass really does belong to one, and only one member of outer class. I have used that construct where OuterClass was a collection of mathematical objects and InnerClass was the actual objects themselves.

Doesn't this defeat the whole purpose of having read-only properties?

I know how to use properties and I understand that they implicitly call underlying get and set accessors, depending on whether we are writing to or reading from a property.
static void Main(string[] args)
{
A a = new A();
(a.b).i = 100;
}
class A
{
private B _b = new B();
public B b
{
get { return _b; }
}
}
class B
{
public int i;
}
What code (a.b).i = 100; essentially does is that first property’s get accessor returns a reference to an object _b, and once we have this reference, we are able to access _b’s members and change their values.
Thus, in our example, having read only property only prevents outside code from changing the value of a reference variable _b, but it doesn’t prevent outside code from accessing _b’s members.
So it seems that property can only detect whether we are trying to read from or write to a variable ( in our case variable _b ) located on the stack, while it’s not able to detect whether we’re trying to also write to members of an object to which the variable on the stack ( assuming this variable is of reference type ) points to.
a) But doesn’t that defeat the whole purpose of having read-only properties? Wouldn’t it be more effective if properties had the ability to also detect whether we’re trying to access members of an object returned by get accessor( assuming backing field is of a reference type )?
thank you
Immutability is not transitive; you can't expect mutable objects into an immutable accessor to be immutable.
Your reference is read only, not your object.
Imagine a class like this:
public class A
{
private List<int> _myList<int> = new List<int>();
public List<int> MyList { get { return _myList; } }
}
Now, users of the class can add and remove and access items in the list, but they cannot replace the list itself. This is important. It allows you to do things inside the class like assume the _myList member is never null, for example.
Put a more general way, this paradigm allows you do define an interface into your class such that users can use the types in the properties you expose, but they cannot just swap instances of complex types out from under you.
No, it does not defeat the purpose of read-only properties.
It is possible to use read-only properties that don't let the user change the underlying data. For example, you can have your property return a System.Collections.ObjectModel.ReadOnlyCollection even though the underlying type is a List. This, of course, won't prevent the user from changing the properties of the items in the collection.
Of course you can access B.i; it's public. You're thinking that since _b is private, all methods should be private when fetched through A? In that case it's pretty useless as you wouldn't be able to use B for anything.
You ask:
Doesn’t that defeat the whole purpose
of having read-only properties?
But look: your B.i member is a public field.
I ask you, then: what is the purpose of having a public field? It only makes sense if you want users of your code to be able to change that field's value. If you don't want that, it should be a private field, or (if you want to provide read but not write access) a property with a private set accessor.
So there's your answer. private B _b serves its purpose in the code you posted quite well (_b cannot be externally set to something new), just as public int i serves its purpose equally well (i can be externally changed).
Reference immutability is a popular feature request. Too bad its is so dramatically non CLS compliant. Very few languages have this notion, I only know of C++ (but don't get out much).
The key problem that this needs to be enforced by the CLR. C++ doesn't need to enforce this at runtime, only a C++ compiler is required to ensure that const contracts are observed. It has no support at all for language interop, beyond a bolt-on like COM.
This won't fly in .NET, there's little point in declaring a reference immutable and have that verified by the compiler when another language can stomp all over it because it doesn't have the syntax to express immutability. I reckon we'll get it some day, not Real Soon.
As a minor point, you don't have to write (a.b).i = 100; but simply
a.b.i = 100;
Back to your question, I don't think it defeats the purpose. You can still not do the following:
a.b = new B();
because there's no public set(). If you want the member i of class B to be read only, you can do the same thing as you did to member _b of class A by making it private and providing a public get(), but not set(). Off the top my head, doing what you propose might lead to many unexpected consistencies (I'm sure the language designers did not overlook this).
Entirely dependent on the situation, but read only access to a mutable object is a commonly used design. In many cases you simply want to ensure that the object itself remains the same.
Some classes (like String object in Java, and I believe in C# as well) are entirely immutable, where as others are only partially mutable. Consider an ActiveRecord style of object for which most fields are mutable, but the ID is immutable. If your class holds an ActiveRecord in a read only property, external classes cannot swap it for a different ActiveRecord object and thus change the ID, which might break assumptions within your class.
I disagree. Your property is for the class B, not for the members of class B. This means you can't assign a new Object to b. It doesn't mean that B's public members suddenly become private.
readonly applies to the class property, not the object that the property refers to. It keeps you from being able to write a.b = new B();, and that is all it does. It places no constraints on what you can do to the object once you get a reference to it. I think what you are discovering is that readonly make the most sense when applied to value types or immutable class types.
Another use case:
interface INamedPerson
{
String Name { get; }
}
class Bob : INamedPerson
{
public String Name { get; set; }
}
class Office
{
// initialisation code....
public INamedPerson TheBoss { get; }
public IEnumerable<INamedPerson> Minions { get; }
}
Now, if you have an instance of the Office, as long as you don't go cheating with casts, you have read-only access to everyone's names, but can't change any of them.
Ah. Encapsulation does the instantiated class inherit the containing class's access level. Exposing type B as a public property of type A. 'B.i' is public so it should be accessible from outside the same way 'A.b' is public.
A.b returns a reference of a privately accessible type B, however type B has a publicly accessible field i. My understanding is that you can set the i field of B but you can't set the b property of A externally. The B type property of A is readonly however the reference to type B does not define the same readonly access to its fields.
I'm sure you can modify the definition of type B to suit your need for the access level of B's fields or properties.

Categories

Resources