What is the usage of global:: keyword in C#? - c#

What is the usage of global:: keyword in C#? When must we use this keyword?

Technically, global is not a keyword: it's a so-called "contextual keyword". These have special meaning only in a limited program context and can be used as identifiers outside that context.
global can and should be used whenever there's ambiguity or whenever a member is hidden. From here:
class TestApp
{
// Define a new class called 'System' to cause problems.
public class System { }
// Define a constant called 'Console' to cause more problems.
const int Console = 7;
const int number = 66;
static void Main()
{
// Error Accesses TestApp.Console
Console.WriteLine(number);
// Error either
System.Console.WriteLine(number);
// This, however, is fine
global::System.Console.WriteLine(number);
}
}
Note, however, that global doesn't work when no namespace is specified for the type:
// See: no namespace here
public static class System
{
public static void Main()
{
// "System" doesn't have a namespace, so this
// will refer to this class!
global::System.Console.WriteLine("Hello, world!");
}
}

Related

How to declare variables and methods globally i.e. outside a class? [duplicate]

How do I declare a variable so that every class (*.cs) can access its content, without an instance reference?
In C# you cannot define true global variables (in the sense that they don't belong to any class).
This being said, the simplest approach that I know to mimic this feature consists in using a static class, as follows:
public static class Globals
{
public const Int32 BUFFER_SIZE = 512; // Unmodifiable
public static String FILE_NAME = "Output.txt"; // Modifiable
public static readonly String CODE_PREFIX = "US-"; // Unmodifiable
}
You can then retrieve the defined values anywhere in your code (provided it's part of the same namespace):
String code = Globals.CODE_PREFIX + value.ToString();
In order to deal with different namespaces, you can either:
declare the Globals class without including it into a specific namespace (so that it will be placed in the global application namespace);
insert the proper using directive for retrieving the variables from another namespace.
You can have static members if you want:
public static class MyStaticValues
{
public static bool MyStaticBool {get;set;}
}
First examine if you really need a global variable instead using it blatantly without consideration to your software architecture.
Let's assuming it passes the test. Depending on usage, Globals can be hard to debug with race conditions and many other "bad things", it's best to approach them from an angle where you're prepared to handle such bad things. So,
Wrap all such Global variables into a single static class (for manageability).
Have Properties instead of fields(='variables'). This way you have some mechanisms to address any issues with concurrent writes to Globals in the future.
The basic outline for such a class would be:
public class Globals
{
private static bool _expired;
public static bool Expired
{
get
{
// Reads are usually simple
return _expired;
}
set
{
// You can add logic here for race conditions,
// or other measurements
_expired = value;
}
}
// Perhaps extend this to have Read-Modify-Write static methods
// for data integrity during concurrency? Situational.
}
Usage from other classes (within same namespace)
// Read
bool areWeAlive = Globals.Expired;
// Write
// past deadline
Globals.Expired = true;
A useful feature for this is using static
As others have said, you have to create a class for your globals:
public static class Globals {
public const float PI = 3.14;
}
But you can import it like this in order to no longer write the class name in front of its static properties:
using static Globals;
[...]
Console.WriteLine("Pi is " + PI);

can't use public access modifier

Sorry if this is a really stupid question, but I am messing around and fiddling with what I am learning from YouTube beginner tutorials and I'm kind of lost here. can anyone let me know why using the public access specifier before the fields break everything?
namespace ConsoleApp1
{
class Methods
{
static void Main(string[] args)
{
public int _first, _second, _third, _fourth, _fifth;
for (int i=1;i<=5;i++)
{
Console.WriteLine("Enter {0}st number:", i);
Console.ReadLine();
switch (i)
{
case 1:
_first = i;
break;
}
}
}
The problem is the scope.
The fields (inside functions or methods it's better use variable) in the scope of a function cannot be "public" or "protected" or... No, are private to the container scope, and, of course, doesn't need access word.
If you make a field outside the function you can make it public, private, internal... etc...
You cannot make fields out of object or structs.
namespace ConsoleApp1
{
public int _secondThing // baaaad
class Methods
{
public static int _thing; //good
int _thing; //good, it's private;
private int _thing; //good, it's the same
public int _firstThing; //good
static void Main(string[] args)
{
public int _first, _second, _third, _fourth, _fifth; //baaad
int _first, _second; //good
}
}
}
As DrkDeveloper mentioned it´s a question of the scope of your variables. Depending on where you define a variable it only exists within that specific scope and all of its child-scopes, but not in parent-scopes. So defining somethin at class-level makes it accessable in the entire class, this is in all of its members. Defining a variable within a member such as a method on the other hand makes that variable existing only in that specific scope - in that method. You can´t access it from anywhere outside its scope.
Your first code without the access-modifier works, because the variables are defined within that method - we call them local variables. The second code with the access-modifiers would turn those variables into members (fields in this case) of the class. So you´d define a member in a method that should have a class-scope. This of course does not work.
So you either leave your variables local, or make them public static within your class.
namespace ConsoleApp1
{
class Methods
{
public int _first, _second, _third, _fourth, _fifth;
static void Main(string[] args)
{
for (int i=1;i<=5;i++)
{
Console.WriteLine("Enter {0}st number:", i);
Console.ReadLine();
switch (i)
{
case 1:
_first = i;
break;
}
}
}
}
}

Define global alias for static classes

I have a static ExceptionHelper that looks like this:
public static class ExceptionHelper
{
public static async void ShowDialog(string message)
{
// Show message
}
}
Whenever I want to call this method I do it like this at the moment:
ExceptionHelper.ShowDialog("This is a message.");
I now thought of defining an alias for the ExceptionHelper to not having to write the whole word each time I want to use it.
I know I can achieve it with using:
using Ex = MyNamespaces.ExceptionHelper;
But then I'd have to define it in each file I want to use the method. Is there a way I can define the alias globally without changing the name of the class? Or is there any attribute I can set above the class declaration?
Extension Method
You could make it an extension method on string.
public static class ExceptionHelper
{
public static async void ShowDialog(this string message)
{
// Show message
}
}
Then you would use it like so:
using WhateverNamespaceExceptionHelperLivesIn;
public class TestClass
{
public void TestMethod()
{
"This is a message".ShowDialog();
}
}
This makes your question moot - you don't have to define an alias at all.
Static imports
An alternative approach is to import the class statically. You won't need an alias, because you can reference the ShowDialog method directly. This will require C#6/Visual Studio 2015.
using static WhateverNamespaceExceptionHelperLivesIn.ExceptionHelper;
public class TestClass
{
public void TestMethod()
{
ShowDialog("This is a message");
}
}
In C# 6.0 you can use static usings:
using static MyNamespace.ExceptionHelper;
Of course not globally, that works only for defines. But in a file where you use this line, you can use the members of the ExceptionHelper without any prefix.
As of C# 10, you can now define gloabl usings.
// GlobalUsing.cs
global using static WhateverNamespaceExceptionHelperLivesIn.ExceptionHelper;
And it will now be available globally, without having to define the class name, or the namespace, at the top of each class.
// Available Globally in the Project
public class TestClass
{
public void TestMethod()
{
ShowDialog("This is a message");
}
}
This might apply, even though you are using a method. You could use an ENUM type instead that lies outside of any namespace and access globals values that way. Place the enum in a file outside of any namespace. You can access it globally that way, or if you have trouble, using the "global" keyword below if you have any trouble referencing it:
enum Size
{
SMALL = 1,
MEDIUM = 5,
LARGE = 10
}
class Test {
int mysize1 = (int)Size.SMALL;
int mysize2 = (int)global::Size.MEDIUM;
}

Static variable initialized more than once using Prism and MEF

Context
I have an InteractionWindowPresenter class in charge of creating Windows. Some of them may be modal and I want to keep a counter of the number of opened modal windows in order to notify other parts of the application.
Therefore I added a _modalsCount variable to the class, updated whenever a modal window is opened or closed:
public class InteractionWindowPresenter<TWindow, TNotification>
where TWindow : System.Windows.Window
where TNotification : Prism.Interactivity.InteractionRequest.INotification
{
private static int _modalsCount = 0;
...
private bool _useModalWindow;
public InteractionWindowPresenter(InteractionRequest<TNotification> request,
bool useModalWindow = false)
{
_useModalWindow = useModalWindow;
}
public void Show()
{
var window = ...
window.Closed += (s, e) =>
{
if (_useModalWindow)
{
_modalsCount = Math.Max(0, --_modalsCount);
if (_modalsCount == 0)
ServiceLocator.Current.GetInstance<IEventAggregator>()
.GetEvent<ModalStatusChanged>().Publish(false);
}
};
if (_useModalWindow)
{
_modalsCount++;
ServiceLocator.Current.GetInstance<IEventAggregator>()
.GetEvent<ModalStatusChanged>().Publish(true);
window.ShowDialog();
}
else
window.Show();
}
}
Upon initialization, each Prism module - ie. each class implementing IModule - instantiates an InteractionWindowPresenter per view that must be shown on a Window and holds a reference to it. For instance:
[ModuleExport("ClientsModule", typeof(Module),
DependsOnModuleNames = new[] { "RibbonModule", "ClientsModelModule" },
InitializationMode = InitializationMode.WhenAvailable)]
public class Module : IModule
{
InteractionWindowPresenter<ClientSelectionWindow, ClientSelection> _selectionPresenter;
public void Initialize()
{
_selectionPresenter =
new InteractionWindowPresenter<ClientSelectionWindow, ClientSelection>
(Interactions.ClientSelectionRequest, useModalWindow: true);
}
}
The InteractionWindowPresenter class is defined in an infrastructure assembly directly referenced by all the modules as well as other infrastructure assemblies. It is not referenced by the launcher application, which is merely a MefBootstrapper. Hence, MEF is used for composition.
The problem
Setting a breakpoint on the _modalsCount initialization line reveals that it is not executed when the InteractionWindowPresenter instances are created. Instead, it is executed the first time (and only that time) the variable is used in each module - ie. the first time the Show method is called from each module. Thus, each module has its own value, shared across all the instances of that specific module.
I understand that the lazy evaluation is due to the curious nature of beforefieldinit. However I expected that evaluation to happen just once for the whole application instead of per module.
I also tried performing the initialization in the static constructor:
static int _modalsCount;
static InteractionWindowPresenter()
{
_modalsCount = 0;
}
In this case, the static constructor is invoked prior to the execution of the instance constructor, but every single time an instance is created. Therefore, the variable seems not to be static anymore.
From my understanding, static variables are initialized once per AppDomain. Thus, since all my assemblies (modules and infrastructure) are in the same AppDomain, this should not happen. Am I wrong in any of these two assumptions?
Work-around employed so far
Creating a simple class to hold the counter avoids this problem:
static class ModalsCounter
{
private static int _modalsCount = 0;
public static int Increment()
{
return ++_modalsCount;
}
public static int Decrement()
{
_modalsCount = Math.Max(0, --_modalsCount);
return _modalsCount;
}
}
Thus replacing the calls to _modalsCount by:
ModalsCounter.Increment();
ServiceLocator.Current.GetInstance<IEventAggregator>()
.GetEvent<ModalStatusChanged>().Publish(true);
and:
if (_useModalWindow && ModalsCounter.Decrement() == 0)
ServiceLocator.Current.GetInstance<IEventAggregator>()
.GetEvent<ModalStatusChanged>().Publish(false);
So what am I missing here? Have I somehow misunderstood the lifecycle and scope of static variables or are Prism modules and/or MEF messing with me?
The static is created once for each Type. Since you are using a Generic Type the number of Types created will be equivalent to the number of combinations of Type variables you use in the initializer. This is why hiding the static inside a non generic class works (probably a better pattern anyhow).
You class is generic, and each constructed generic type (with type arguments specified) is a separate type. Each of them has its own set of static members.
From C# language specification, section 4.4.2 Open and closed types:
Each closed constructed type has its own set of static variables, which are not shared with any other closed constructed types. Since an open type does not exist at run-time, there are no static variables associated with an open type.
You can make a simple test:
public class Test<T>
{
public static object obj = new object();
}
Console.WriteLine(object.ReferenceEquals(Test<string>.obj, Test<object>.obj)); // false
Your workaround (keeping the static counter in a non-generic class) is correct.

Why is the double colon(::) operator required to resolve a namespace conflict? [duplicate]

This question already has answers here:
What is the purpose of :: in C#?
(2 answers)
Closed 9 years ago.
Please see my below sample program. I have two namespaces containing the same struct. To avoid conflict while using in Main(), I have given the namespaces aliases. While invoking the struct from Main(), I am able to invoke directly through namespace alias, like test.MyStruct. I have another option also using :: operator, like test::MyStruct.
Why is the :: operator required, and where should I use it instead of an alias?
using System;
using test=counter;
using duplicatecounter;
namespace counter
{
struct MyStruct
{
}
}
namespace duplicatecounter
{
struct MyStruct
{
}
}
class Program
{
public static void Main()
{
test.MyStruct a = new test.MyStruct();
test::MyStruct a1 = new test::MyStruct();
}
}
It is mainly needed when someone wrote code without consideration of code being used. I.e. duplicate classes in namespaces that are expected to be used together or hiding namespaces.
MSDN sample shows one case in Use the Global Namespace Alias :
class TestApp
{
// Define a new class called 'System' to cause problems.
public class System { }
// Define a constant called 'Console' to cause more problems.
const int Console = 7;
const int number = 66;
static void Main()
{
// The following line causes an error. It accesses TestApp.Console,
// which is a constant.
//Console.WriteLine(number);
global::System.Console.WriteLine(number); // ok
}
}
the :: operator doing the same like namespace.
,but the :: operator is used to look up identifiers. It is always positioned between two identifiers
example :
global::System.Console.WriteLine("Hello World");
a good example explained here : http://msdn.microsoft.com/en-us/library/c3ay4x3d.aspx

Categories