What is lazy initialization. here is the code i got after search google.
class MessageClass
{
public string Message { get; set; }
public MessageClass(string message)
{
this.Message = message;
Console.WriteLine(" *** MessageClass constructed [{0}]", message);
}
}
Lazy<MessageClass> someInstance = new Lazy<MessageClass>(
() => new MessageClass("The message")
);
Why should I create an object in this way?
When actually we need to create object in this way?
The purpose of the Lazy feature in .NET 4.0 is to replace a pattern many developers used previously with properties. The "old" way would be something like
private MyClass _myProperty;
public MyClass MyProperty
{
get
{
if (_myProperty == null)
{
_myProperty = new MyClass();
}
return _myProperty;
}
}
This way, _myProperty only gets instantiated once and only when it is needed. If it is never needed, it is never instantiated. To do the same thing with Lazy, you might write
private Lazy<MyClass> _myProperty = new Lazy<MyClass>( () => new MyClass());
public MyClass MyProperty
{
get
{
return _myProperty.Value;
}
}
Of course, you are not restricted to doing things this way with Lazy, but the purpose is to specify how to instantiate a value without actually doing so until it is needed. The calling code does not have to keep track of whether the value has been instantiated; rather, the calling code just uses the Value property. (It is possible to find out whether the value has been instantiated with the IsValueCreated property.)
"Lazy initialization occurs the first time the Lazy.Value property is accessed or the Lazy.ToString method is called.
Use an instance of Lazy to defer the creation of a large or resource-intensive object or the execution of a resource-intensive task, particularly when such creation or execution might not occur during the lifetime of the program."
http://msdn.microsoft.com/en-us/library/dd642331.aspx
Check out msdn documentation over here : Lazy Initialization
Lazy initialization of an object means that its creation is deferred until it is first used. Lazy initialization is primarily used to improve performance, avoid wasteful computation, and reduce program memory requirements.
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.
We have recently started taking our business logic that relies heavily on DevForce and exposing it over a web API. We have been very careful to avoid threading issues by ensuring each request has its own set of entities, its own EntityManager, etc. However, we've started noticing logical deadlocks (in the .net code, not in SQL) when there are a lot of concurrent requests.
I've tracked down the problem to locking that is done by the PropertyInterceptors. We use them quite extensively and have cases where the interceptor on one property (Property A) will set another property (Property B) but that the converse is also true (setting B will also set A). The exact reasons for some of these cases are complicated but the basic idea is that we have some properties that we want to keep in sync. It seems that there is locking inside the PropertyInterceptor logic so we can easily hit deadlocks because the order in which those locks are taken can vary.
I've created a simple reproducible case below that involves an Entity with just two properties. One is an integer property and the other a string property. I have BeforeSet logic to keep these two in sync with each other. In the simple case of settings the properties one at a time, everything works. But since we are dealing with a web api, it's very common for things to execute in parallel. If we get one request that happens to set IntValue and another request that happens to set StringValue, we'll hit a deadlock. This is true even though we are talking about two different entities in two different EntityManagers. From our perspective, we are doing everything in a thread safe manner but then DevForce has some very long-lived locks which we know can be dangerous.
Here is the code which hopefully explains things. Keep in mind our actual code is much more complicated but the basic deadlock is the same:
public static void ReproduceDeadlock()
{
var e1 = new MyEntity();
var e2 = new MyEntity();
//This works - settings fields one at a time is fine
e1.IntValue = 1;
e2.StringValue = "2";
//But if we introduce some concurrency, we'll become deadlocked
Task.Run(() =>
{
//Wait a bit so e1.IntValue has a chance to start
Thread.Sleep(1000);
e2.StringValue = "22";
});
e1.IntValue = 11;
//Execution will never make it hear...setting the IntValue will never complete
}
public class MyEntity : Entity
{
[BeforeSet("StringValue")]
public void BeforeSetStringValue(PropertyInterceptorArgs<MyEntity, string> args)
{
//When the string is set, 'sync' it to the IntValue property
IntValue = int.Parse(args.Value);
}
[BeforeSet("IntValue")]
public void BeforeSetIntValue(PropertyInterceptorArgs<MyEntity, int> args)
{
//When the int is set, 'sync' it to the StringValue property
//Introduce a delay so the deadlock will obviously happen. In our real app, we don't have
// a Thread.Sleep() but we do have non-trivial logic that can cause just enough delay for the deadlock
// to happen sometimes
Thread.Sleep(2000);
StringValue = args.Value.ToString();
}
#region PropertyMetadata stuff
public class PropertyMetadata
{
public static readonly DataEntityProperty<MyEntity, string> StringValue =
new DataEntityProperty<MyEntity, string>("StringValue", true, false,
ConcurrencyStrategy.None, false, null,
false);
public static readonly DataEntityProperty<MyEntity, int> IntValue =
new DataEntityProperty<MyEntity, int>("IntValue", true, false,
ConcurrencyStrategy.None, false, null,
false);
}
public string StringValue
{
get { return PropertyMetadata.StringValue.GetValue(this); }
set { PropertyMetadata.StringValue.SetValue(this, value); }
}
public int IntValue
{
get { return PropertyMetadata.IntValue.GetValue(this); }
set { PropertyMetadata.IntValue.SetValue(this, value); }
}
#endregion
}
}
Stephen, maybe I do have a workaround for you. In the interceptor actions you can use SetValueRaw to sync the value to another property and avoid going through its interceptor (and validation). The method is available on the public IStructuralObject interface, which, although documented as for internal use only, is not something we plan to change. Both the EntityAspect and ComplexAspect classes implement this interface.
So your example would look like this:
[BeforeSet("StringValue")]
public void BeforeSetStringValue(PropertyInterceptorArgs<MyEntity, string> args)
{
//When the string is set, 'sync' it to the IntValue property
(this.EntityAspect as IStructuralObject).SetValueRaw(PropertyMetadata.IntValue, int.Parse(args.Value));
}
[BeforeSet("IntValue")]
public void BeforeSetIntValue(PropertyInterceptorArgs<MyEntity, int> args)
{
//When the int is set, 'sync' it to the StringValue property
//Introduce a delay so the deadlock will obviously happen. In our real app, we don't have
// a Thread.Sleep() but we do have non-trivial logic that can cause just enough delay for the deadlock
// to happen sometimes
Thread.Sleep(2000);
(this.EntityAspect as IStructuralObject).SetValueRaw(PropertyMetadata.StringValue, args.Value.ToString());
}
I'll note one other workaround too. The deadlock is in the interceptor, but you can have all the usual validation logic and change notification occur, just without the interception layer. One way to do this is to set the EntityGroup.PropertyInterceptionEnabled flag to false, but it's usually pretty clumsy to turn this on and off. Another option is a helper function to do exactly what the SetterInterceptor is doing:
public static void SetValueWithVerification(IStructuralObject so, DataEntityProperty property, object newValue)
{
if (so.VerifierEngine != null && so.VerifierEngine.Enabled && so.EntityGroup.VerificationEnabled)
{
if ((property.MemberMetadata.VerifierSetterOptions & VerifierSetterOptions.BeforeSet) > 0)
{
so.ValidatePropertyBeforeSet(property, newValue);
}
so.SetValueWithChangeNotification(property, newValue);
if ((property.MemberMetadata.VerifierSetterOptions & VerifierSetterOptions.AfterSet) > 0)
{
so.ValidatePropertyAfterSet(property, newValue);
}
}
else
{
so.SetValueWithChangeNotification(property, newValue);
}
}
Then call this in these tightly coupled interceptor actions:
SetValueWithVerification(this.EntityAspect, PropertyMetadata.StringValue, args.Value.ToString());
Are there issues with returning a new instance from an accessor? If so, is there a better approach?
public class Person
{
private RecIpDet _ipDet;
public RecIpDet IpDet
{
get
{
if(_ipDet == null)
_ipDet = new RecIpDet();
return _ipDet;
}
}
}
There are issues, because you never set your field, so you'll return a new object everytime the property is called.
You should set _ipDet if it's null, and then return it. This is called lazy instantiation or lazy initialization.
public class Person
{
private RecIpDet _ipDet;
public RecIpDet IpDet
{
get
{
if (_ipDet == null)
{
_ipDet = new RecIpDet();
}
return _ipDet;
}
}
}
Keep in mind, this is not thread-safe, so if that's a factor for you, you'll need a more robust mechanism. For single threaded applications, this method of lazy instantiation is fine.
If you're using .NET 4.0 or higher, you can use the Lazy<T> class, which I believe is thread-safe:
public class Person
{
private Lazy<RecIpDet> _ipDet = new Lazy<RecIpDet>(() => new RecIpDet());
public RecIpDet IpDet
{
get
{
return _ipDet.Value;
}
}
}
For us it is common practice to use:
get
{
return _ipDet ?? (_ipDet = new RecIpDet());
}
Based on your comment, it does appear you meant to set the instance, so this is a classic example of lazy instantiation which is fine (though not thread-safe). If you do not need to worry about thread safety, then by all means this will work:
get
{
if (_ipDet == null)
_ipDet = new RecIpDet();
return _ipDet
}
But if you're in .NET 4.0 I'd recommend Lazy<T> instead of building your own lazy construction:
public class Person
{
private Lazy<RecIpDet> _ipDet = new Lazy<RecIpDet>();
public RecIpDet IpDet
{
get { return _ipDet.Value; }
}
}
Lazy's Value calls the constructor for the type on first call and is thread-safe (you can choose different) levels of thread-safety as well..
As of now you will always return a new object. Unless somehow _ipDet got set to a value. This makes your code behave very unpredictable.
Either implement the singleton pattern and replace return new RecIpDet(); with _ipDet = new RecIpDet(); or make it always return a new object, which is fine.
It's quite unusual to use Lazy Instantiation, most of the time it's for the Singleton pattern, here you'll find more info on that :
Implementing Singleton pattern
In this page you'll even find a way to make it thread-safe.
It can be very useful for global objects that can be accessed from anywhere in your application.
I tried to find a similar question on SO but had no luck. Apologies if it's a duplicate.
What are drawbacks to instantiating class-type variables when they are declared?
In a lot of classes representing Business Object Model we have things like this:
public class RateArea {...}
public class FlatRateSchedule
{
public string ScheduleID {get;set;}
public decimal MaxAmount {get;set;}
}
public class PricingData
{
private List<RateArea> rateAreaList = new List<RateArea>();
private FlatRateSchedule flatRateSchedule = new FlatRateSchedule();
public List<RateArea> RateAreaList
{
get { return rateAreaList; }
set { rateAreaList = value; }
}
public List<FlatRateSchedule> FlatRateScheduleList
{
get { return flatRateScheduleList; }
set { flatRateScheduleList = value; }
}
}
At some point this PricingData class is initialized and some properties are hydrated (but not always all properties).
The thinking being that we're creating "blank" instances of classes so that no properties are ever null. This is convenient because we never have to check if any property is null before accessing it's members. Whether properties are hydrated or not, they would never be "null" to the consuming class. If the properties aren't initialized then code needs to check for null every time before accessing a property.
Is a blanket convention that "all properties of a class should be initialized at all times and never be null" really bad?
Besides using some resources to instantiate and store these "default" class instances, the savings in null-exception-checking code seem to be worth it. Are we missing something?
Not an expert here but
If its a List, it does need to be initialized since you can't add elements if it isn't.
If, throughout the life of your class, your properties may not be always needed you can lazy load them.
You could use .Net 4.0's Lazy<T> class.
From Msdn : "Use an instance of Lazy to defer the creation of a large or resource-intensive object or the execution of a resource-intensive task, particularly when such creation or execution might not occur during the lifetime of the program."
Other than that I think it would be intensive for all your properties to be null and have every consuming class do null checks. Lazy<T> solves this.
I like to initialize values to avoid having to check for null throughout my application. I'd probably go with lazy loading:
public List<RateArea> RateAreaList
{
get {
rateAreaList = rateAreaList ?? new List<RateArea>();
return rateAreaList;
}
set { rateAreaList = value; }
}
As long as your properties are only lists (as in your example), it may be a good convention, making your code more compact and easier to read. Lists can be empty, and if you don't need to distinguish between an empty list and a null reference, this works fine. But if your properties contain other "Business Objects", this may not work so easily. Often the construction of those "child" Business Objects cannot or shall not be done at the time when the "parent" object is constructed.
I have a class (Foo) which lazy loads a property named (Bar). What is your preferred way to protect against mistaken use (due to intellisense or inexperienced staff) of the uninitialized backing field?
I can think of 3 options:
class Foo {
// option 1 - Easy to use this.bar by mistake.
string bar;
string Bar {
get {
// logic to lazy load bar
return bar;
}
}
// option 2 - Harder to use this._bar by mistake. It is more obscure.
string _bar2;
string Bar2 {
get {
// logic to lazy load bar2
return _bar2;
}
}
//option 3 - Very hard to use the backing field by mistake.
class BackingFields {
public string bar;
}
BackingFields fields = new BackingFields();
string Bar3 {
get {
// logic to lazy load bar
return fields.bar;
}
}
}
Keep in mind, the only place I want people mucking around with the backing field bar is in setter and getter of the property. Everywhere else in the class they should always use this.Bar
Update
I am currently using the following Lazy implementation (not for all properties with backing fields, but for select ones that require lazy loading, synchronization and notification). It could be extended to support futures as well (force evaluation in a separate thread in a later time)
Note My implementation locks on read, cause it supports an external set.
Also, I would like to mention that I think this is a language limitation which can be overcome in Ruby for example.
You can implement lazy in this way.
x = lazy do
puts "<<< Evaluating lazy value >>>"
"lazy value"
end
puts x
# <<< Evaluating lazy value >>>
# lazy value
How about use of ObsoleteAttribute and #pragma - hard to miss it then!
void Test1()
{
_prop = ""; // warning given
}
public string Prop
{
#pragma warning disable 0618
get { return _prop; }
set { _prop = value; }
#pragma warning restore 0618
}
[Obsolete("This is the backing field for lazy data; do not use!!")]
private string _prop;
void Test2()
{
_prop = ""; // warning given
}
Option 5
Lazy<T>
works quite nicely in several situations, though option 1 should really be just fine for most projects so long as the developers aren't idiots.
Adding [EditorBrowsable(EditorBrowsableState.Never)] to the field won't help if it is private since this logic only kicks in for intellisense generated from metadata rather than the current code (current project and anything done via project references rather than dlls).
Note: Lazy<T> is not thread safe (this is good, there's no point locking if you don't need to) if you require thread safety either use one of the thread safe ones from Joe Duffy or the Parallel Exetensions CTP
I usually go for option 2, as it is easier to spot mistakes later on, although option 1 would pass a code review. Option 3 seems convoluted and whilst it may work, it's not going to be nice code to revisit 6 months down the line whilst trying to refactor/fix a bug/etc.
Option 1, coupled with some education.
Rationale: software is meant to be read more often than written, so optimize for the common case and keep it readable.
Code reviews will catch misuse so just go with the most readable. I dislike attempts to work around bad programmers in code, because 1) they don't work, 2) they make it harder for smart programmers to get their work done, and 3) it addresses the symptom rather than the cause of the problem.
I usually just go for option 1. Because it is a private field I don't think it really an issue, and using something like the wrapper class as in your option 3 only makes code difficult to read and understand.
I would just put a large comment block on the top of the class that would look like that:
/************************************************************
* Note: When updating this class, please take care of using *
* only the accessors to access member data because of *
* ... (state the reasons / your name, so they can ask *
* questions) *
*************************************************************/
Usually, just a note like that should be enough, but if this is the same for all the classes in the project, you might prefer to put it in a simple document that you give to programmers working on the project, and everytime you see code that isn't conform, you point them to the document.
Automatic properties:
public int PropertyName { get; set; }
will prevent access to the backing field. But if you want to put code in there (e.g. for lazy loading on first access) this clearly won't help.
The simplest route is likely to be a helper type which does the lazy loading, and have an private field of that type, with the public property calling to the correct property/method of the helper type.
E.g.
public class Foo {
private class LazyLoader {
private someType theValue;
public someType Value {
get {
// Do lazy load
return theValue;
}
}
}
private LazyLoader theValue;
public someType {
get { return theValue.Value; }
}
}
This has the advantage that the backing field is harder to use than the property.
(Another case of an extra level of indirection to solve problems.)
// option 4
class Foo
{
public int PublicProperty { get; set; }
public int PrivateSetter { get; private set; }
}
C# 3.0 feature, the compiler will generate anonymous private backing fields which can't be accessed by mistake, well unless you use reflection...
EDIT: Lazy instantiation
You can have laziness like this:
// I changed this with respect to ShuggyCoUk's answer (Kudos!)
class LazyEval<T>
{
T value;
Func<T> eval;
public LazyEval(Func<T> eval) { this.eval = eval; }
public T Eval()
{
if (eval == null)
return value;
value = eval();
eval = null;
return value;
}
public static implicit operator T(LazyEval<T> lazy) // maybe explicit
{
return lazy.Eval();
}
public static implicit operator LazyEval<T>(Func<T> eval)
{
return new LazyEval(eval);
}
}
Those implicit conversion make the syntax tidy...
// option 5
class Foo
{
public LazyEval<MyClass> LazyProperty { get; private set; }
public Foo()
{
LazyProperty = () => new MyClass();
}
}
And closures can be used to carry scope:
// option 5
class Foo
{
public int PublicProperty { get; private set; }
public LazyEval<int> LazyProperty { get; private set; }
public Foo()
{
LazyProperty = () => this.PublicProperty;
}
public void DoStuff()
{
var lazy = LazyProperty; // type is inferred as LazyEval`1, no eval
PublicProperty = 7;
int i = lazy; // same as lazy.Eval()
Console.WriteLine(i); // WriteLine(7)
}
}
Currently, I'm in a similar situation.
I have a field which should only be used by its property accessor.
I can't use automatic properties, since I need to perform additional logic when the property is set. (The property is not lazy loaded as well).
Wouldn't it be great if a next version of C# would allow something like this:
public class MyClass
{
public int MyProperty
{
int _backingField;
get
{
return _backingField;
}
set
{
if( _backingField != value )
{
_backingField = value;
// Additional logic
...
}
}
}
}
With such construct, the _backingField variable's scope is limited to the property.
I would like to see a similar language construction in a next version of C# :)
But, I'm afraid this feature will never be implemented:
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=381625
This might be overly simple, but why not abstract all the lazy to a base class
public class LazyFoo{
private string bar;
public string Bar{
get{
// lazy load and return
}
set {
// set
}
}
}
public class Foo : LazyFoo{
// only access the public properties here
}
I could see the argument that it is unnecessary abstraction, but it is the simplest way I can see to eliminate all access to backing fields.
This seems like trying to design-out mistakes that might not happen in the first place, and basically it's worrying about the wrong thing.
I would go with option 1 + comments:
///<summary>use Bar property instead</summary>
string bar;
///<summary>Lazy gets the value of Bar and stores it in bar</summary>
string Bar {
get {
// logic to lazy load bar
return bar;
}
}
If you do get a developer who keeps using the backing variable then I'd worry about their technical competence.
By all means design to make your code easier to maintain, but try to keep it simple - any rule that you make for yourself here is going to be more hassle than it's worth.
And if you're still really worried about it create an FxCop (or whatever you're using) rule to check for this sort of thing.
Option 6:
Makes it very dumb indeed if you use it.
string doNotUseThisBackingField_bar6;
string Bar6 {
get {
// logic to lazy load
return doNotUseThisBackingField_bar6;
}
}
Option 4 (a new solution):
See if the question is really about how to prevent people from using an uninitialized variable then init it with an KNOWN INVALID value.
I would say something like:
string str = "SOMETHING_WRONG_HERE";
Who ever is using 'str' will have some sort of warning.
Otherwise Option 3 if preventing users from using 'str' is more important than readability etc.