I have a class with like 20 fields which get populated from SQL database on load. Currently I am calling load data method right after the constructor, which calls SQL proc and populate all the required fields. At times, I may not access the these 20 fields at all, I am adding additional cost of SQL call even though it was not required. So I changed all the properties to have an associated private property and when the program calls the public property, first I check the private property and if it is null that means we need to load data from sql so I call the load method. It works great, but when I see the code, there is a repeated pattern of null check and load the sql query. Is there a better way of doing this?
private string _name;
public string Name
{
get {
if (_name == null)
LoadData(); //this popultes not just but all the properties
return _name;
}
}
Btw C# now has default lazy-loaders implementation. Why not to use it, instead of providing isSomethingLoaded flags? :)
public class Bar
{
private Lazy<string> _name = new Lazy<string>(() => LoadString());
public string Name
{
get { return _name.Value; }
}
}
In case of non-static LoadString method, lazy-loader should be initialized in constructor;
Nope, this is right. Here is the wikipedia article. The overhead of the null check will be very minimal compared to unnecessary database calls. Now, if the users of the program actually use the values 99% of the time, then I would say this pattern is not needed.
Just one note of caution: If any of your values could possibly be null, then you will make unnecessary database calls. It might be better to do something like this (which will be an even quicker check since it is just a bit check):
//Constructor default to not loaded
bool isLoaded = false;
private string _name;
public string Name
{
get {
if (!isLoaded)
LoadData(); //this popultes not just but all the properties
return _name;
}
}
private LoadData()
{
//Load Data
isLoaded = true;
}
Well you could change it to:
if (!initialized)
LoadData();
And in your LoadData set initialized to true, but that really doesn't change the semantics of it.
One thing you can do is to extract if into separate method so each property contains just one additional call:
void EnsureData()
{
if (!dataLoaded)
LoadData(); //this populates all the properties
}
public string Name {
get {
EnsureData();
return _name;
}
}
I think you should consider your application structure. Why would you even instantiate the class if you are not going to be using the properties? I believe it's actually cleaner for you to call the SQL after your constructor code but only create the objects of your class if you are going to be using it. The other more flexible solution is making the LoadData public and calling it as needed from the object instance as needed.
I am in the learning process of design patterns. i have one suggestion if you load data only once you can try with singleton design pattern.
public class Singleton123
{
private static readonly string _property1 = ClassLoadData.LoadData();
public static string MyProperty1
{
get
{
return _property1;
}
}
}
public class ClassLoadData
{
public static string LoadData()
{
// any logic to load data
return "test";
}
}
Call property as below
Singleton123 obj = new Singleton123();
string stra = Singleton123.MyProperty1;
string strb = Singleton123.MyProperty1;
this property will be loaded only once.
Related
I'm working with some C# code that's using .Net 4 Lazy loads and I'm not super familiar with it. I'm trying to figure out if this particular code is useless or not.
Originally the property and code below where in the same class, but now I've moved the code to an external class that no longer has access to the private "lazyRecords" property. I'm wondering what the point of checking "lazyRecords.IsValueCreated" is since the lazyRecords.Value has not been invoked yet, wouldn't it always be false? Or is it checking to see if another thread somehow invoked the Value? Or is it doing this in case of a thread exception that resulted in not loading the object?
Property:
private Lazy<List<Record>> lazyRecords;
public List<Record> Records
{
get
{
return lazyRecords.Value;
}
set
{
lazyRecords = new Lazy<List<Record>>(() => value);
}
}
Code:
public Category LoadCategory(BaseClient client)
{
Category category = new Category();
category.Records = client.RecordClient.GetRecordsByCategoryID(category.ID);
if (lazyRecords.IsValueCreated)
{
category.WorldRecord = category.Records.FirstOrDefault();
}
else
{
category.WorldRecord = client.RecordClient.GetWorldRecord(category.ID);
}
}
The code is pretty useless, yes. To help you understand why, consider this very minimal version of Lazy (the real class has more options and logic to take care of multiple threads, but this is the rough idea):
public class Lazy<T>
{
private readonly Func<T> _creator;
private T _cachedValue;
public Lazy(Func<T> creator) => _creator = creator;
public bool IsValueCreated { get; private set; }
public T Value
{
get
{
if (!IsValueCreated)
{
_cachedValue = _creator();
IsValueCreated = true;
}
return _cachedValue;
}
}
}
The delegate passed to the constructor is called on demand, the first time the Value is requested. In the code you've posted there is no point to this because the delegate simply returns the value passed into the setter.
As to the LoadCategory method, the code you posted is hard to decipher. It directly accesses lazyRecords, implying it's a method of the same class. But then it accesses Records on a different object.
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.
private Lazy<Image> _headshot = new Lazy<Image>(LoadHeadshotFromHDD);
public Image Headshot
{
get
{
return _headshot.Value;
}
set
{
_headshot = new Lazy<Image>(() => value);
}
}
Let's say I have a Person class and Headshot property is in that class. Headshot is loaded from HDD so I want it to be lazy, but I also want to implement setter for that property. Will there be a problem with the way that I've implemented this? I'm just not sure that I'm using it correctly.
There's really no point in using lazy loading if you already have the object in memory (in the setter case), but it's perfectly fine to do it this way. One thing I can think of, is if you'd check the _headshot.IsValueCreated, it'll return false, even though you already have the object in memory. Another alternative would be
private Image _headshot;
public Image Headshot
{
get { return _headshot ?? (_headshot = LoadHeadshotFromHDD()); }
set { _headshot = value; }
}
This will lazy load the headshot when the property is accessed, just like when using Lazy<T>, but it'll set the value directly, so you can check _headshot != null instead of _headshot.IsValueCreated. You should check out Jon Skeet's Singleton Pattern post.
Looks ok, however, if you'd take the initialization to the constructor, you could have less code.
public class Foo
{
public Foo()
{
this.Headshot = new Lazy<Image>( () => LoadHeadshotFromHDD );
}
public Lazy<Image> Headshot { get; set; }
}
Do I need to declare a class-level variable to hold a property, or can I just refer to self.{propertyname} in the getter/setter?
In other words, can I do this? (where I haven't defined mongoFormId anywhere):
public string mongoFormId
{
get
{
return this.mongoFormId;
}
set
{
this.mongoFormId = value;
revalidateTransformation();
}
}
You can either use automatic accessors or implement your own. If you use automatic accessors, the C# compiler will generate a backing field for you, but if you implement your own you must manually provide a backing field (or handle the value some other way).
private string _mongoFormId;
public string mongoFormId
{
get { return this._mongoFormId; }
set
{
this._mongoFormId = value;
revalidateTransformation();
}
}
UPDATE: Since this question was asked, C# 6.0 has been released. However, even with the new syntax options, there is still no way to provide a custom setter body without the need to explicitly declare a backing field.
You need to set a field variable and store the value there, if you're going to use custom getter and setter.
With the code you have right now you will be running into a stack overflow exception. When you assign something to mongoFormId, you'll execute the line this.MongoFormId = value;. This is an assignment to mongoFormId, resulting in executing the line this.MongoFormId = value;, and so on. It won't ever stop.
The correct way is a field:
private string _mongoFormId;
public string mongoFormId {
get { return this._mongoFormId; }
set {
this._mongoFormId = value;
revalidateTransformation();
}
}
You should have a backing variable. Take a closer look:
get { return this.mongoFormId; }
Is going to call the getter on mongoFormId, which will call that code again, and again, and again! Defining a backing variable will avoid the infinite recursive call.
Check MSDN Properties Overview
While a property definition generally includes a private data member,
this is not required. The get accessor could return a value without
accessing a private data member. One example is a property whose get
method returns the system time. Properties enable data hiding, the
accessor methods hide the implementation of the property.
You can do it both the ways.
If you want to have a class level member variable then do it this way -
public class sampleClass
{
private string _mongoFormId;
public string mongoFormId {
get { return _mongoFormId; }
set {
_mongoFormId = value;
revalidateTransformation();
}
}
}
Or do this simple in class, if no need for revalidateTransformation() execution call there
public class sampleClass
{
public string mongoFormId {get; set;}
}
This won't work since you get a recursive call to the property.
If I'm not mistaken, the result will be a StackOverflowException.
You must use a variable.
private string mongoFormId;
public string MongoFormId
{
get
{
return this.mongoFormId;
}
set
{
this.mongoFormId = value;
revalidateTransformation();
}
}
If you don't have to execute revalidateTransformation, you can use the auto-property.
This will create a backingfiled for you behind the scene.
public string MongoFormId { get; set; }
With the code you wrote, you are creating a recursive endless loop on both the get and set. The this keyword refer to the current class, not the property you are in.
So yes, you need to declare a private field. And to avoid confusion, create properties following the MSDN Naming Guideline (Use Pascal case for properties, camel case for private fields). And please do the same for your methods, it should be RevalidateTransformation instead of revalidateTransformation if you follow the C# convention instead of java's.
private string mongoFormId;
public string MongoFormId
{
get
{
return mongoFormId;
}
set
{
mongoFormId = value;
RevalidateTransformation();
}
}
public string mongoFormId {
get {
return this.mongoFormId;
}
set {
this.mongoFormId = value;
revalidateTransformation();
}
}
this way you have the Function recursive on all paths
The only way i see is to use a private data member. As other boys tells.
Per the MSDN documentation, the following syntax is used:
// A read-write instance property:
public string Name
{
get { return name; }
set { name = value; }
}
However, the following code is generated by VS2010 automatically for a new library class:
public string Name
{
get
{
String s = (String)ViewState["Name"];
return ((s == null) ? String.Empty : s);
}
set
{
ViewState["Name"] = value;
}
}
When is it appropriate to use the ViewState syntax over the shorter example shown on MSDN?
ViewState is a feature of ASP.Net server controls that persists information across postbacks.
For simple properties that aren't in a server control, you should use an auto-implemented property:
public string Name { get; set; }
The first stores the value in a private property field inside the class, while the second (tries to) store the actual value in the ViewState.
So the 2nd is only possible when you are talking about ASP controls with viewstate enabled, which is a narrow subset of all possible cases.
A C# property is just a piece of syntactic sugar. This structure
public Foo MyValue { get ; private set ; }
is exactly as if you coded:
private Foo _myValue ;
public Foo
{
get
{
return _myValue ;
}
private set
{
this._myValue = value ;
}
}
In either case, the code that actually gets generates is pretty much this:
private Foo _myValue ;
public Foo MyValue_get()
{
return this._myValue ;
}
private Foo MyValue_set( Foo value )
{
this._MyValue = value ;
}
If you opt to instantiate your own getter/setter, then what happens in the body of the getter/setter is entirely up to you. There is no "right" or wrong: it's dependent on the needs of your program.
With respect to ViewState, ViewStateis a piece of ASP.Net. It has little do with properties one way or another. You example just exposes a ViewState item as a public read/write property.
The difference between the two is that one is just plain old C# property providing access to a (most likely) privately scoped variable in your class.
The other one is returning a value recovered from ASP.NET's ViewState.
These are two different things altogether.