I have this code;
using System;
namespace Rapido
{
class Constants
{
public static const string FrameworkName = "Rapido Framework";
}
}
Visual Studio tells me: The constant 'Rapido.Constants.FrameworkName' cannot be marked static
How can I make this constant available from other classes without having to create a new instance of it? (ie. directly accessing it via Rapido.Constants.FrameworkName)
public static class Constants
{
public const string FrameworkName = "Rapido Framework";
}
A const is already static as it cannot change between instances.
You don't need to declare it as static - public const string is enough.
Related
I have a class where there's a public static variable that I want to access from another class. Here's the class :
In GlobalVariable.cs
public class GlobalVariable
{
public static int MoisVS = 3;
}
And I want to access to "MoisVS" from another class. Here's the class :
In ArretPage.cs
var globalvariable = new ProjetTN.Class.GlobalVariable();
globalvariable.MoisVS; //<--- Make something like that.
I know it's possible in a WinForm app but is that possible in a Xamarin.forms app ?
You defined your MoisVS as static so you can't access it from an instance variable. Accessing static members of a class you're using the class name itself. So for example accessing your MoisVS will look like:
GlobalVariable.MoisVS
If you want to accesss it as an instance property you have to change your class to:
public class GlobalVariable
{
public int MoisVS = 3;
}
If there are only static or const values in your class. You can also decide to make your whole class static
public static class GlobalVariable
{
public static int MoisVS = 3;
public const string MyString = "";
}
this will prevent you from using the new keyword to create an instance of that class.
I will break this into steps.
1) File -> New File -> General -> Choose Empty Class -> Name it (e.g.UICONTROL_NAMES)
2) Add the following: (Sample code)
using System;
namespace iOSControls.HelperClass
{
public static class UICONTROL_NAMES
{
public const string textField = "Text Fields";
public const string inputTextField = "Input types - TextFields";
public const string button = "Buttons";
public const string label = "Label";
}
Have a note:
UICONTROL_NAMES class is inside a folder group called HelperClass and iOSControls is the project name.
3) On your ViewController.cs, add namespace directive.
using iOSControls.HelperClass;
using Foundation;
4) Access const strings in UICONTROL NAMES:
string controlName = UICONTROL_NAMES.textField;
Is there a nice way to set a constant to be that of a classes namespace?
namespace ACMECompany.ACMEApp.Services
{
public class MyService
{
private const string WhatWeDo = "ACMECompany.ACMEApp.Services";
private const string WouldBeNice = typeof(MyService).Namespace;
...
}
}
So that if the class if moved to another namespace we don't need to worry about these constants.
More Info
The constant is only really used for logging - where it is passed to some log method. This is all legacy code so wont be changing in the short term. I am aware of runtime ways to get this information such as This Question
We're using .NET 4 but will be upgrading soon to .NET 4.5.
You're not going to set a constant variable with a non-constant value. This is understandable, isn't it?
BTW, C# has the readonly keyword, to turn any class field to work like a constant once object construction time ends. They can or can't be static:
public class MyService
{
static MyService()
{
WouldBeNice = typeof(MyService).Namespace;
}
private static readonly string WouldBeNice;
}
or...
public class MyService
{
private static readonly string WouldBeNice = typeof(MyService).Namespace;
}
Also, you can achieve the same behavior using read-only properties:
// Prior to C# 6...
public class MyService
{
private static string WouldBeNice { get { return typeof(MyService).Namespace; } }
}
// Now using C# 6...
public class MyService
{
private static string WouldBeNice => typeof(MyService).Namespace;
}
// Also using C# 6...
public class MyService
{
// This can be even better, because this sets the namespace
// to the auto-generated backing class field created during compile-time
private static string WouldBeNice { get; } = typeof(MyService).Namespace;
}
I was mildly surprised when the compiler complained about this:
public class UsefulClass
{
public const String RatingName = #"Ratings\rating";
}
public class OtherClass
{
public void SomeFunc()
{
UsefulClass useful = new UsefulClass();
String rating = useful.RatingName;
}
}
Compiler says, "Static member cannot be accessed with an instance reference; qualify it with a type name instead"
This isn't a problem, String rating = UsefulClass.RatingName; works fine. I'm just curious what the thinking is behind this? I have an instance of a public class with a public constant on it, why can't I get the data this way?
Because constants just aren't instance members; they're statically bound to their respective types. In the same way you can't invoke static methods using instances, you can't access class constants using instances.
If you need to get a constant off an instance without knowing its type first-hand, I suppose you could do it with reflection based on its type.
If you're trying to add a member that can't be modified but pertains to instances, you probably want read-only fields or properties instead.
A "variable" marked const is a compile time construct, not an instance member. You can access it like you would a static variable:
public void SomeFunc()
{
UsefulClass useful = new UsefulClass();
String rating = UsefulClass.RatingName; // Access as if static
}
That being said, I would personally wrap this into a property if it's meant to be used as you described, like so:
public class UsefulClass
{
private const string ratingName = #"Ratings\rating";
public string RatingName { get { return ratingName; } }
}
This would make your syntax work, but also be a better design, IMO, since it doesn't expose your constants publically.
Because const in c# are implicitly of static type. And As static members can be accessed only on class member and not on instance, const cannot too.
So here is what I'm thinking...
public class MyClass
{
public const string MyConstant = "MyConstantValue";
private static MyClass DefaultInstance;
static MyClass()
{
DefaultInstance = new MyClass();
}
}
...
NotificationService.RegisterForNotification(MyClass.MyConstant, Callback);
Will this work or do I need to use something like a static readonly property field to trigger the static constructor?
Use of a constant doesn't necessarily result in a member access which would cause the static constructor to be called. The compiler is allowed to (encouraged, even) substitute the value of the constant at compile time.
Your suggested workaround of static readonly should be ok, although readonly suggests a field, not a property. Properties are read-only when they have no setter, the readonly keyword isn't involved.
A simple example:
class HasSConstructor
{
internal const int Answer = 42;
static HasSConstructor()
{
System.Console.WriteLine("static constructor running");
}
}
public class Program
{
public static void Main()
{
System.Console.WriteLine("The answer is " + HasSConstructor.Answer.ToString());
}
}
Output under .NET 4.0:
The answer is 42
The static constructor never runs!
Static constructor is called automatically before the first instance is created or any static members are referenced. See here: MSDN: Static Constructors
By the way, constant fields are inherently static, but as pointed they may (and probably will) be substituted by the value itself.
The static constructor will not be called if you're just accessing public constants. For example, consider this class:
class Testo
{
public const string MyValue = "Hello, world";
public static readonly int xyzzy;
static Testo()
{
Console.WriteLine("In static constructor");
xyzzy = 27;
}
}
Now, in another class, execute:
Console.WriteLine(Testo.MyValue);
Console.WriteLine(Testo.xyzzy);
Your output will be:
Hello, world
In static constructor
27
Constants are hoisted from the class at compile time. So the value of Testo.MyValue does not reference the Testo class at runtime. The static constructor is not called until you call something that requires initialization.
So, yes, you need to access something like a static readonly if you want to ensure that the constructor is called.
No, you don't need such. Static constructor is called when the class is loaded.
im trying to understand the get and set properties for fields, and run in to this issue, can somone explaine to me why i had to make the int X field Static to make this work?
using System;
namespace ConsoleApplication1
{
class Program
{
public static int X = 30;
public static void Main()
{
var cX = new testme();
cX.intX = 12;
Console.WriteLine(cX.intX);
cX.intX = X;
Console.WriteLine(cX.intX);
Console.ReadKey();
}
}
class testme
{
public int intX
{
get;
set;
}
}
}
Because you were using the field in a static context, in this case the method publicstaticvoid Main. Since your Program class just runs statically there is no instance and therefore you can't access any instance members.
because it is used in a static method
Since Main is static, you cannot access non-static instances from outside of it.