I have a static string class for my database so that I always spell the tables and columns they way they were designed.
I've currently got about 500 lines of code in this one class, but here is a short example:
public const string PURCHASING = "PURCHASING";
public const string SCHED_PURCH = "SCHED/PURCH";
public const string SCHEDULING = "SCHEDULING";
To create a readonly static string array of the "Clerk" department, I use this static declaration:
public static string[] CLERK_DEPT {
get {
return new string[] { PURCHASING, SCHEDULING, SCHED_PURCH };
}
}
There are many lines of code like this in my database strings class.
Today, I happened across this active post where someone was doing something very similar:
How do I prevent the modification of a private field in a class?
The answer there provided a way to provide a readonly string array that I had not considered before:
You must return a copy of your array.
public String[] getArr() {
return arr == null ? null : Arrays.copyOf(arr, arr.length);
}
That has me wondering now if someone out here knows of a more efficient way of passing back my readonly string array.
I must admit that I've always abhorred the idea of the return new string[] in my code.
So, is there? ...a more efficient and cleaner way of doing this or have I already created the best solution?
There's no such thing as an immutable array, basically.
If you trust all your callers, you could tell them not to mutate the array. An alternative is to provide a read-only wrapper:
private static readonly ReadOnlyCollection<string> clerkDepartments =
new ReadOnlyCollection<string>(
new[] { "PURCHASING", "SCHED/PURCH", "SCHEDULING" });
public static readonly ReadOnlyCollection<string> ClerkDepartments
{ get { return clerkDepartments; } }
Note that although ReadOnlyCollection<T> isn't a totally immutable collection, only code with access to the underlying collection could change it - and as the only code which "knows" about the array is the initializer which passes it to the constructor, you're basically safe unless someone cracks out reflection :)
Perhaps use a ReadOnlyCollection?
http://msdn.microsoft.com/en-us/library/ms132474.aspx
Related
I understand that reading from the WebConfigurationManager is slow, so I want to minimize my use of it.
Say I have the following readonly property in my code:
public string SiteLogo {
get {
return WebConfigurationManager.AppSettings["SITE_LOGO"];
}
}
In C# 6.0, I can shorten this so that the "getter" has the default value:
public string SiteLogo { get; } = WebConfigurationManager.AppSettings["SITE_LOGO"];
This, it looks like, would be called every time the class is instantiated, whether that Property is ever used or not.
It looks like the most efficient call is still to declare a Private variable to use in the Property:
public string SiteLogo
{
get
{
if (String.IsNullOrEmpty(_siteLogo))
{
_siteLogo = WebConfigurationManager.AppSettings["SITE_LOGO"];
}
return _siteLogo;
}
}
private string _siteLogo;
This still requires me to create Private variables for all of my getters, which seems overly tedious.
I have discarded the idea of using a Session variable, because reading that and casting it to a String seems like it would still incur more overhead.
I would like to see is a way to Auto Assign the Private Property if it is needed.
If the compiler called each Property's Private field #this, I could use something along these lines:
public string SiteLgo
{
get
{
if (String.IsNullOrEmpty(#this))
{
#this = WebConfigurationManager.AppSettings["SITE_LOGO"];
}
return #this;
}
}
Even better, I should not ever need to explicitly tell the code block to return the Private Property, since that is the getter's job:
public string SiteLogo
{
get
{
if (String.IsNullOrEmpty(#this))
{
#this = WebConfigurationManager.AppSettings["SITE_LOGO"];
}
}
}
If a technique to do that currently exists, I don't know the name of what to call it to look it up.
Have I missed the better way to do what I am after (accessing the Private value without having to create it)?
You missed some class that was introduced in .NET 4.0: Lazy<T>:
private readonly string _siteLogo = new Lazy<string>(() => WebConfigurationManager.AppSettings["SITE_LOGO"]);
// Lazy<T>.Value will call the factory delegate you gave
// as Lazy<T> constructor argument
public string SiteLogo => _siteLogo.Value;
BTW, I wouldn't use lazy-loading for this case... at the end of the day, application settings are already loaded into memory and you aren't accessing from the file.
In fact, AppSettings is a NameValueCollection and it uses hash codes to store keys (taken from MSDN):
The hash code provider dispenses hash codes for keys in the
NameValueCollection. The default hash code provider is the
CaseInsensitiveHashCodeProvider.
In other words, accessing AppSettings has a time complexity O(1) (constant).
I would use lazy-loading if you would need to parse settings some way to avoid re-parsing them everytime.
My example:
class MyClass
{
public int a = 1;
public static List<MyClass> list = new List<MyClass>();
}
class Program
{
static void Main(string[] args)
{
MyClass.list.Add(new MyClass() { a = 5 });
MyClass.list.Add(new MyClass() { a = 10 });
foreach (MyClass item in MyClass.list) Console.WriteLine(item.a);
Console.ReadKey();
}
This code works, and shows that my list, which is statically defined within the MyClass class itself, is populating as I'd expect.
Is there any reason not to define my list in this manner?
Such a solution is used sometime, f.e. to implement the Singleton or Register-Resolve patterns.
But you should keep in mind that it's not well suited for multithread environment. Typically, a static collection should be private, and access methods (including property getter and setter) should be synchronized.
In additional, static fields/properties are difficult to an unit testing.
Actually this code shows a lot of sign of (very) bad desing.
First of all one better doesn't make fields public. All other classes/object can now alter the value of that variable in objects. Perhaps you don't see much problems with that, but imagine that at one point in time you want to restrict the range of values that variable can have, or that it depends on the value of another field. Properties (with getters and setters) and methods are used to shield an field from external usage, they need to guarantee that the object always remains in a valid state.
Next about the list, again don't make such lists public - unless you are confident that there is no problem -. But furthermore using statics is by some researchers considered to be bad design as well. The list maintains a state, but since it is static, this is a global state. Global states are problematic since they don't allow (easy) unit testing, and can become problematic if for some reason the list should be not that global.
In case you really want to make some access point for data, you can perhaps consider making a class that stores such list and pass it around in your program.
There are a few exceptions, for instance the Flyweight pattern where one indeed maintains a global state. Those examples are merely used to increase performance. For instance:
public class FlyWeightInstance {
private int value; //<- private field
private static Dictionary<int,FlyWeightInstance> dic = new Dictionary<int,FlyWeightInstance>(); //<- private static cache
private int FlyWeightInstance (int value) { // <-- private constructor
this.value = value;
}
public static FlyWeightInstance (int value) {
FlyWeightInstance res;
if(!dic.TryGetValue(value,out res)) {
res = new FlyWeightInstance(value);
dic.Add(value,res);
}
return res;
}
}
Okay, I am way outside my comfort zone here and am struggling with new concepts but I hope I can make myself clear.
As I understand it, global variables are very bad in C# (and are dangerous in general) but I don't really want to get into that debate. After some research I am led to believe that Singletons can help. Please feel free to offer alternatives here if that is wrong with the situation I describe below.
What I am trying to do is create a dynamic multi-dimensional array which will contain numerical data. This matrix will be varying in size and must be created during runtime (I am pulling data from a logging device through a GUI).
What I see being a solution is to create a class which has a variable which can I can get and set but with a dynamic size.
public class mySingleton
{
public static int dataSize { get; set; }
public double[] dataSet = new double[dataSize] { get; set; }
}
Something to this effect but obviously this is wrong and does not work. I have been trying to research how to initialize an array at runtime but cannot figure it out, but I also feel like I don't know which terms to search. Any help?
What you probably want to do is use explicit (rather than implicit) backing fields so that you can add logic to your getter and setter. Something like this:
public class mySingleton
{
private static int _dataSize; // you might want to set this to some sensible default
public static int DataSize
{
get { return _dataSize; }
set
{
_dataSize = value;
_dataSet = null; // changing the size will implicitly clear the array - but you could write code to resize if you really wanted to
}
}
private static double[] _dataSet;
public static double[] DataSet
{
get
{
if (_dataSet == null)
{
_dataSet = new double[_dataSize];
}
return _dataSet;
}
// you can include a setter if you want to let the consumer set the dataset directly - in which case it should update the _dataSize field.
}
}
You may want to initialize the array in response to the set method on your dataSize property. You won't be able to use the quick "autofill" properties ("get; set;"), but that way you will be able to initialize the data set as soon as a user sets the data size.
So something like this:
public class mySingleton
{
private static int _dataSize;
public static int dataSize {
get {return _dataSize;}
set {
_dataSize = value;
dataSet = new double[value];
}
}
public double[] dataSet { get; private set; }
}
In general, to set a static property of a class, you can use a static constructor (http://msdn.microsoft.com/en-us/library/k9x6w0hc(v=vs.80).aspx) or control the flow of access to the class/data in a way that you can set up the static members before someone else needs to use them.
You can create an array of dynamic size easily:
double[] array = new double[size];
size can be any arbitrary expression of type int. So your code would look like this:
class ArrayHolder { public static double[] Value; } //global state
//set the global state somewhere else in your code:
var size = DetermineSize();
double[] array = new double[size];
ArrayHolder.Value = array; //publish globally
After having initialized the array it is available in the entire program. Arrays are reference types so there is no needless data copying here.
Sidenote: Why would you prefer a singleton to a static variable? Often they have the same pros and cons (IOW no meaningful difference). In my example I just used a static variable.
I am not sure if a Singleton suits best for your approach, but anyway, here is a Singleton Implementation:
public class MatrixSingleton
{
private static readonly MatrixSingleton instance = new MatrixSingleton();
static MatrixSingleton()
{
}
private MatrixSingleton()
{
this.Data = new List<Tuple<double, double>>();
}
public static MatrixSingleton Instance
{
get { return instance; }
}
public List<Tuple<double, double>> Data;
}
and the using of it
MatrixSingleton matrixSingleton = MatrixSingleton.Instance;
matrixSingleton.Data.Add(new Tuple<double, double>(1.1, 2.2));
For more information about the Singleton pattern these links might help:
http://braindrivendevelopment.com/2013/05/04/simplify-singleton-pattern/
http://www.csharpindepth.com/Articles/General/Singleton.aspx
One of my projects has a value type/struct that represents a custom identifier string for a video format. In this case, it's going to contain a content type string, but that can vary.
I've used a struct so it can be strongly type when it's passed around, and perform some sanity checks on the initial string value.
public struct VideoFormat {
private string contentType;
public VideoFormat(string contentType) {
this.contentType = contentType;
}
public string ContentType {
get { return this.contentType; }
}
public override string ToString() {
return this.contentType;
}
// various static methods for implicit conversion to/from strings, and comparisons
}
As there are a few very common formats, I've exposed these as static read only fields with default values.
public static readonly VideoFormat Unknown = new VideoFormat(string.Empty);
public static readonly VideoFormat JPEG = new VideoFormat("image/jpeg");
public static readonly VideoFormat H264 = new VideoFormat("video/h264");
Is it better to expose the common values as static read only fields or as get only properties? what if I want to change them later? I see both methods used throughout the .Net framework, e.g. System.Drawing.Color uses static readonly properties while System.String has a static read only field for String.Empty, and System.Int32 has a const for MinValue.
(Mostly copied from this question but with a more specific and not directly related question.)
Properties are a good idea unless you are declaring something that never changes.
With properties you can change the inside implementation without affecting programs consuming your library and handle changes / variations. Consuming programs wont break and wont require to be recompiled.
e.g. (I know this is a bad example but you get the idea..)
public static VideoFormat H264Format
{
get{
// This if statement can be added in the future without breaking other programs.
if(SupportsNewerFormat)
return VideoFormat.H265;
return VideoFormat.H264;
}
}
Also keep in mind that if you decided to change a field to a property in the future, consuming code breaks.
I want to have a large number of class instances return the same similar fields of data, like in this example implementation:
foreach (SomeClass sc in SomeClasses)
{
System.Console.WriteLine(sc.GetData("1st field"));
System.Console.WriteLine(sc.GetData("Another field"));
System.Console.WriteLine(sc.GetData("and another"));
}
// ---- inside SomeClass:
Dictionary<string, string> myData;
public string GetData(string field)
{
return myData[field];
}
What I don't like is the string hashing, lookup and matching that has to happen over and over again in the example (I assume thats how Dictionary works). I would really like to find a better approach.
Coming from the C world, I thought of assigning all fields a unique integer key, such that I can change into an array lookup:
// ---- inside SomeClass:
string[] MyData;
public string GetData(int field_key)
{
return MyData[field_key];
}
Now the field lookup is efficient, but it just doesn't feel right in these "arrays are evil" times, and it is tedious and error prone to deal with the field_key integer.
I don't know if I'm chasing performance ghosts here, its just that I want to find a design that is both efficient and clean.
Suggestions?
Why don't you want a dictionary look-up? A very efficient implementation of a dictionary would be an index look up of the hash in an array. So the underlying implementation could boil down to the code in your second example. This would make it O(1)
Use the Dictionary
Because the fields are not known at compile time, but rather dynamic and user configurable, I'm going to modify your example program slightly to use an array of properties. Then I'd advocate an approach similar to yours but using your own custom class (here, called MyProperty) rather than string. Performance will be at least as good as (and maybe a tad better than) the string approach, but the benefit is that it gives you more flexibility: if you ultimately decide for performance reasons that you need to use an array or List approach, you can easily embed an array index into your MyProperty class. You'd have to change the implementation of GetData but not your calling code.
public static void Test1() {
SomeClass[] SomeClasses; //created somehow
//in real life, this would be determined dynamically
var properties=new[] {SomeClass.FirstField, SomeClass.AnotherField, SomeClass.AndAnother};
foreach(var sc in SomeClasses) {
foreach(var property in properties) {
Console.WriteLine(sc.GetData(property));
}
}
}
public class SomeClass {
public static readonly MyProperty FirstField=new MyProperty();
public static readonly MyProperty AnotherField=new MyProperty();
public static readonly MyProperty AndAnother=new MyProperty();
private readonly Dictionary<MyProperty, string> myData=new Dictionary<MyProperty, string>();
public string GetData(MyProperty property) {
return myData[property];
}
}
//default implementation of Equals and GetHashCode are fine here
public class MyProperty {}
HOWEVER, since your target application is really about collecting a set of dynamic and user configurable property getters, maybe you really want to make some Funcs? Code like the below will be very fast, and it still has the ability you want, namely it allows you to make a little dynamic, user-configurable list of property getters.
public static void Test2() {
SomeClass[] SomeClasses; //created somehow
//in real life, this would be determined dynamically
var getters=new[] {SomeClass.FirstField, SomeClass.AnotherField, SomeClass.AndAnother};
foreach(var sc in SomeClasses) {
foreach(var getter in getters) {
System.Console.WriteLine(getter(sc));
}
}
}
public class SomeClass {
public static readonly Func<SomeClass, string> FirstField=sc => sc.field0;
public static readonly Func<SomeClass, string> AnotherField=sc => sc.field1;
public static readonly Func<SomeClass, string> AndAnother=sc => sc.field2;
private string field0;
private string field1;
private string field2;
}
If your instances have the same fields, why not just use properties?
foreach (SomeClass sc in SomeClasses)
{
System.Console.WriteLine(sc.FirstField);
System.Console.WriteLine(sc.AnotherField);
System.Console.WriteLine(sc.AndAnother);
}
First, if you're not sure this actually is a performance problem for you, then yes, you are chasing performance ghosts and your current implementation is fine.
But if you found out during profiling that you really need to make this code faster, then your seems fine. “Arrays are evil” is mostly true only in public interfaces, it's fine to use them for implementation.
One thing I would change about your code though: create an enum containing the fields and use that instead of int. It's just as fast and much more readable. If the fields are not known at compile time, using int is fine. If you do know some of the fields at compile time, you could use static properties for them.