I have a mainForm variable that is used nearly everywhere in my program. I'd like to be able to reference to this variable without having to type the name of the class that holds this variable (i.e. instead of Global._mainForm, I should be able to just type _mainForm to access this variable anywhere within the same namespace).
What is the best way to accomplish this?
Anytime I see a global anything I get worried, so I would reconsider how your program is architected. You can almost always get away without having a globally accessible object. Although there are legitimate reasons to have a globally accessible object, usually I try to stay away from them.
From the little information you've given, you might be able to use events to talk to the main window instead of directly accessing it.
If you do have real need for a globally accessible object then you could do something like this
Note: In the code below everything is static, conversely you could create a special static class that holds a reference to the instance of the class you're really interested in. But there is no way that I'm aware of to hold a global reference that is outside of all namespaces to an instance of an object.
using Bar = ProbablyAReallyBadIdeaToHaveAGlobalAnythingButHeyWhyNot.TestClass;
namespace ProbablyAReallyBadIdeaToHaveAGlobalAnythingButHeyWhyNot
{
public static class TestClass
{
public static int TestFoo { get; set; }
}
}
namespace Foo.SomeOtherNamespace
{
class MyClassThatDoesStuff
{
public void DoStuff()
{
Bar.TestFoo = 123;
}
}
}
You can't accomplish this in C#.
Namespaces are simply part of the type name of a class. Lexically, you can think of a namespace as containing only other namespaces and classes.
Classes may contain fields, functions, events, properties, nested classes, etc., but not nested namespaces.
Therefore there is no way to to define a symbol in a namespace outside of class that aliases or refers to a symbol contained in a specific class.
When resolving the reference to the variable name _mainForm, the only place that it does not require additional qualification is from within the scope of the class that it is defined in.
If you are in a namespace scope that is the same as as the class that defines _mainForm (and _mainForm is a static instance), then you only need access it by qualifying it with the class name. Otherwise you will require additional namespace qualification, or perhaps trickery with a using directive. But outside of the containing class, you will always require a qualification of some kind to access _mainForm.
See http://en.csharp-online.net/ECMA-334:_10.7_Scopes for excruciating detail.
The only way I can see, in C#, for every class in a namespace to be able to directly address the same variable is by defining the variable as static in a base class used by all other classes in the namespace. Since static variables can be addressed as local variables within the class (or classes inheriting from) they are defined in, the variable will be available without class qualifications.
Can't say it is a good idea, but that's not what you asked ...
Related
I am trying to study about nested class in c#. After reading many documents and goggling, I still not yet clear about when to use nested classes. But as far as I understand I did a small sample program. I am pasting my code below. Is this nested class program implemented in correct logic? . What actually a nested class using for ?. and also I have a doubt arise in this program and I specified that doubt in the program. Please help me ...
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Bank bankObj = new Bank();
bankObj.CreateAccount();
bankObj.ShowMyAccountNumber();
}
}
class Bank
{
static int accountNumber; // here if I just declare this as int accountNumber without static it showing an error in the CreatePersonalAccount(int accNo) method's first line ie accountNumber = accNo; as "Cannot access a non-static member of outer type." What actually this error mean ?
public class BankAccountSection
{
public bool CreatePersonalAccount(int accNo)
{
accountNumber = accNo;
return true;
}
}
public void CreateAccount()
{
bool result = new BankAccountSection().CreatePersonalAccount(10001);
}
public void ShowMyAccountNumber()
{
MessageBox.Show(accountNumber.ToString());
}
}
Nested classes are usually used for small utility classes that have no use outside the enclosing (outer) class. For that reason, nested classes are usually private. (There's even an FxCop rule for that.)
Your code
In your case, the nested class BankAccountSection is not really useful, since it has no state by itself. CreatePersonalAccount might as well just be a method of the outer class.
Regarding static int accountNumber;: This will make accountNumber a shared field across all Bank objects, which defeats the whole purpose. Don't do that. If you really need to set a field of the Bank object inside the inner class, you need to pass a reference of the Bank object to the inner class. (This is different to Java, where such a reference is available automatically under some circumstances.) In your particular case, just get rid of the inner class.
Examples for legitimate use cases
You have a large algorithm inside a method. You realize that extracting this algorithm into its own class using many small methods and instance variables would increase readability. Since the algorithm is very specific and probably not useful for other classes, you put the algorithm into an inner class. Thus, you avoid cluttering your outer class with instance variables only used by that algorithm.
You create a List data structure, which is internally implemented as a linked list. Since you don't expose the list nodes to the outside world, you make the nodes an inner class.
Related:
Why/when should you use nested classes in .net? Or shouldn't you?
You seem to think that nested classes in C# behave how they do in Java. That in other words, unless a nested class is declared as static, that it will share the instance of the enclosing class. In C# this is not the case. There is no such thing as that sort of thing in C# -- all nested classes are implicitly static.
This is why you cannot access accountNumber from the nested class unless that field is declared static. (Since the nested class has no access to any particular instance) The idomatic solution to this problem in C# is to pass the instance of the enclosing class into the nested class (presumably by passing this via a constructor argument when instantiating it).
First, that's not a nested class, they are just two classes in one file.
Now, even if it were a nested class, this would probably be an example of when NOT to use nested classes. You should definitely separate your logic from your GUI logic.
I'm don't really think you should be using nested classes anyway, they are in my opinion hard to mantain, but I might be wrong. If I really needed to use nested classes I'd probably do so only when the child class is tightly related.
The error is because you can not access a member of a non static class without its object.
if you do so then it must be declared static.
I have noticed for high demand in my projects for objects such as textboxes or buttons public.
Is there any problems by setting them public?
What does public, private, static really mean?
Access Modifiers (C# Programming Guide)
public
The type or member can be accessed by any other code in the same
assembly or another assembly that references it.
private
The type or member can be accessed only by code in the same class or
struct.
protected
The type or member can be accessed only by code in the same class or
struct, or in a class that is derived from that class.
internal
The type or member can be accessed by any code in the same assembly,
but not from another assembly.
protected internal
The type or member can be accessed by any code in the assembly in
which it is declared, or from within a derived class in another
assembly. Access from another assembly must take place within a class
declaration that derives from the class in which the protected
internal element is declared, and it must take place through an
instance of the derived class type.
There is no security risk as far as I know. But there may be better alternative approach to design your program
public, private, etc are called access modifiers and determine the rules for which other code are allowed to access each member.
There is no technical problem of setting controls as public. But I would not recommend it. Having everything public is a good recipe for creating spaghetti code.
Keep all access to controls within your form and expose only a small set of public methods with a simple interface for external actors to access data and operations on the form.
You should not, for a clean design.
You should in reality put the logic of your application outside forms!
However, if you want to keep logic inside forms, you should at least expose them with public properties and methods, without giving direct access to form controls.
For example you can provide things like a method "EnableSave" or "QuitApplication" or "UpdateState".
Public, private and static deal with scope and what can talk to the objects / methods
Public -> Other classes can create an instance of your class (assuming the class is public) and call this object / method directly
Private -> Other classes can create an instance of your class (assuming the class is public) but can NOT access this object / method
Static -> Other classes can directly access this object / method (assuming class is public and method is public static) such as: YourClassName.ObjectOrMethod without having to create an instance of YourClassName
The best access modifier to give to a gui component when you want to access it directly is :internal (that is the default in VB.NET for example).
However you shouldn't give a public or internal modifier on a GUI control and you shouldn't access it directly, because the presentation layer and business logic layer should be kept separated in a well designed architecture ...
Today, I ran into some code that goes like this.
namespace Foo
{
public enum Game{ High, Low};
public enum Switch{On, Off};
public class Bar()
{
// Blah
}
}
I could not figure out what the difference between that and declaring the enums inside the class was. AFAIK, you can still "override" those enums inside the class.
Enums are types, just like classes. When you declare an enum inside a class, it's just a nested type. A nested enum just hides other enums with the same name that are declared in outer scopes, but you can still refer to the hidden enum through its fully qualified name (using the namespace prefix, in your example).
The decision whether to declare a top level enum or a nested enum depends on your design and whether those enums will be used by anything other than the class. You can also make a nested enum private or protected to its enclosing type. But, top level enums are far more common.
If you put the enumerations in the class, you would need to specify the class name every time you use it outside of the class, for example:
SomeLongClassName x = new SomeLongClassName(SomeLongClassName.Game.High, SomeLongClassName.Switch.On);
instead of:
SomeLongClassName x = new SomeLongClassName(Game.High, Switch.On);
You could decide to put the ennumeration inside a class if it's used only by that class, but that kind of isolation only works for classes. If you have an enumeration that is only used by a single method, you can't put it inside the method.
I want to create a class outside a namespace so that its default access modifier is 'PRIVATE'. I am doing like this:
namespace KnowStructs
{
class Clas1 {}
}
class MyClass {}
But still my class 'MyClass' is referred as Internal when I look in Reflector.
Can anyone help me out.
From Accessibility Levels:
Top-level types, which are not nested in other types, can only have internal or public accessibility. The default accessibility for these types is internal.
and:
Access modifiers are not allowed on namespaces. Namespaces have no access restrictions.
and for private:
Private members are accessible only within the body of the class or the struct in which they are declared
That is, the private keyword is explicitly defined in terms of a containing class or struct.
So whatever you're trying to do, I don't understand it. How could a top level private type possibly be useful? No other code would be able to reference it (in any way, even if it had e.g. static factory methods).
If a private class is allowed that is not a nested type then what would that mean? If it is more restrictive than internal then how would you use it or create an instance. Any use case will require it to be internal at a minimum. I would like to see how you intend to use it.
It simply makes no logical sense.
Whereas having a private nested class scopes itself to the parent containing class. If it were internal then you still will be able to make an instance within the assembly.
So for classes having no modifier is internal by default for non nested types and private for nested types as .Net always applies the most restrictive access when no modifier is specified.
You can make the class internal, if you only want to be accessible by classes in your namespace
I have two objects that I will be mainly use inside of single class. I will initialize them at the beginning and use them throughout the life of the program. Now, my question is that if I should just create them as global variables and access them anywhere in the code (in side of single class) or I should create them as local variables and pass them as parameters to other functions. I just want to see what would be the best programming practice.
I am using C#.
Thanks.
In general you should avoid global variables. If it will be practical, I recommend keeping them as locals and passing them as parameters to your functions.
As Josh pointed out, if these variables are only used inside a single instance of the class, then you should just make them private (or protected) members of that class and be done with it. Of course, then they could only be passed in as parameters to other methods with the same access level (IE, private).
Alternatively, you may consider using the Singleton Design Pattern, which is slightly cleaner (and preferable) to using globals.
If the scope of the objects is the lifetime of the class they are instantiated in, then they should be private member variables.
If they do not maintain state themselves, then you should make them static classes.
You should still pass them around as variables, or at least create property accessors to get at the backing field. This way you can change implementation details without blowing up your code.
SOLID design principles are a good place to start when thinking about these things.
I have two objects that I will be
mainly use inside of single class. I
will initialize them at the beginning
and use them throughout the life of
the program.
This sounds like a perfect time to use a private static readonly variable. These can be initialized in their declaration, or you can make a static constructor to initialize them.
The fact that you are only referencing these objects within a single class is key point. There are other better ways to do things if these objects are ever needed outside of the single class.
If the objects will be the same for every instance of the class then
static const double PI = 3.14158;
You should generally use accessor methods (e.g. getters and setters) and keep your internal variables private. This way the rest of your code, outside of your class, is not dependent on your actual variables.
See this tutorial.
If your class is dependent on these 2 objects then they should probably be members on the class itself. Something like this (where A is the class you are talking about and B is one of the objects you initialize:
public class A
{
private B _b;
public A(B b)
{
_b = b;
}
public void DoSomething()
{
//do something with _b;
}
private void DoSomethingElse()
{
//do something else with _b;
}
}
In this example A is dependent on B (so you pass your instance of B into A's constructor or through some Dependency Injection framework). It wouldn't make a lot of sense for every method on class A to need a parameter of type B to be passed to it.
I think in this case you should ask what makes more sense. Is there some kind of relationship between the 2 objects and the new class. Also, how often are they used in the class.
Generally, If only a couple of methods use the objects, pass them around otherwise, instantiate them as class level variables (possibly using private static readonly as Jefferey suggests) and use them in the class. Making the code more readable should be your goal here.