What is the best way of initializing objects for properties without setters in C#?
For example I have property of type UserData and I can initialize it:
In constructor
In getter
private UserData _user;
public UserData User
{
get
{
return _user?? (_user= new UserData ());
}
}
Initialize field:
private UserData _user = new UserData()
I found few similiar threads:
Create an object in the constructor or at top of the class
C# member variable initialization; best practice?
But it is consideration between 1st and 3rd option - no one thinks about 2nd option - do you know way? From some time it is my preffered option to get objects, but I wonder if there are some cons that I don't know.
Could you tell me what is the best option and what problem could make use of 2nd option?
It all depends on what you want to do with it, so there is definite answer for that.
One difference between 1+3 and 2 is predictability.
With 1+3, you know exactly where your object is created and at which point during instantiation of your class. That can be desirable in some circumstances.
With 2, you depend on external influences (who accesses the property at which time) to initialize the field.
With the delayed creation in approach 2 (only create the object if needed), you could save some time when creating an object of the containing class.
If the UserData's creation takes a lot of time, like, when you have to query a database for it, you might want to delay its creation until really necessary. The object that contains the UserData object is constructed faster since it doesn't need to wait for the UserData object to be created. If the property isn't always accessed, you might even get to completely avoid creating a UserData instance.
If you're simply using plain data, initializing the backing field at its definition (if possible) is preferred:
// when you create constructor N+1, no worries about forgetting to set the value
private UserData _userData = new UserData();
public UserData User
{
get { return _userData; }
}
If you need initialization to be deferred, your best option is using Lazy<T>:
private Lazy<UserData> _userData = new Lazy<UserData>(() => new UserData());
public UserData User
{
get { return _userData.Value; }
}
The constructor for Lazy<T> contains overloads which can address your thread safety needs:
None: access from multiple threads is "undefined behavior"
PublicationOnly: the first thread to complete initialization "wins"
ExecutionAndPublication: locks ensure only one thread initializes the value
One issue with #2 is if the property could be accessed by multiple threads you could potentially create two copies of the UserData object. An additional consideration with #2 is if UserData is expensive to create you will be paying the cost of creating that object when the property is accessed rather than when the containing object is created. That may or may not be desirable depending on your use case.
Related
I have a function that returns a Dictionary<uint, SomeClass> this function is called every second updating data to my list.
Right now, used like this to update my property:
MyData = Api.GetData();
And my property as:
public static Dictionary<uint, SomeClass> MyData { get; private set; }
Is that method fine to update my Dictionary or how should it be done?
I mean, the Dictionary is constantly being replaced as it is right now, right? So if I am using or updating any entry of that Dictionary say:
MyData[SomeValidKey].SomeProperty
My reference would become null or invalid? Or it would simple use a copy of it? Or this is something that would only have a chance to ever happen depending on how fast MyData is queried and the such?
What would be an optimal way to update my Dictionary, while allowing other parts of my application to freely access and use it?
The dictionary is mainly read only and/or call functions of a given item in the Dictionary that is part SomeClass.
UPDATE:
Since MyData = Api.GetData(); means the list is actually replaced? If so if an entry that previously existed no longer exist but any of my functions still had it in use, it would cause exceptions? If an item that was previously used is updated I would not have the updated data as my reference is dead?
So the way I am updating my Dictionary is clearly wrong?
If you're updating your Dictionary in a separate thread then you should use proper locking mechanism to ensure that you're reading the current value. Use lock for both read/write. Also there is a ConcurrentDictionary class in .NET 4 (or above) which is designed for concurrent operations.
But if you're using your dictionary in a single thread then you shouldn't worry about locking at all. Here is an example to demonstrate what happens when you change the reference to another someClass instance:
private class SomeClass
{
public string Name { get; set; }
}
...
Dictionary<uint, SomeClass> dic = new Dictionary<uint, SomeClass>
{
{ 1u, new SomeClass { Name = "1"}},
{ 2u, new SomeClass { Name = "2"}}
};
var sc1 = dic[1]; // sc1 refers to old instance of SomeClass
dic[1] = new SomeClass { Name = "new" }; // now we change the reference here
string oldName = sc1.Name; // oldName is still "1", because sc1 points to the old instance
Your question is different to your example. Your example states you are replacing your dictionary when you call your API. Your question corresponds to updating.
If you were to update your dictionary, then you can either assign the return of your Api call to a temporary dictionary, then transfer/add/delete values in MyData or pass MyData to your Api function and handle that functionality there. This would keep your references in tact if accessed from other parts of your application.
If this isn't possible, then you cannot guarantee that there aren't to be errors from other parts of your code when you replace your MyData object with your Api call. The easiest solution here would that you do not cache your MyData entry value but instead cache its key. Other parts of your application can then check if their cached key is valid and take appropriate action.
If it helps, the following question is in the context of a game I am building.
In a few different places I have the following scenario. There exists a parent class, for this example called Skill, and I have a number of sub-classes implementing the methods from the parent class. There also exists another parent class that we will call Vocation. The skills need to be listed in different sub-classes of Vocation. However, those skills need to be available for anything in the game that uses any given vocation.
My current setup is to have an Enum called Skill.Id, so that Vocation contains a collection of values from that Enum and when an entity in the game takes on that Vocation the collection is passed into another class, called SkillFactory. Skill.Id needs a new entry every time I create a new Skill sub-class, as well as a case in the switch block for the new sub-classes' constructor.
i.e.:
//Skill.Id
Enum{FireSkill,WaterSkill,etc}
//SkillFactory
public static Skill Create(Skill.Id id)
{
switch(id)
{
case Skill.Id.FireSkill:
return new FireSkill();
//etc
}
}
This works perfectly fine, but using the enum and switch block as a go between feels like more overhead than I need to solve this problem. Is there a more elegant way to create instances of these Skill sub-classes, but still allows Vocation to contains a collection identifying the skills it can use?
Edit: I am fine throwing out the enum and associated switch block, so long as Vocation can contain a collection that allows arbitrary instantiation of the Skill sub-classes.
You can make a Dictionary<Skill.Id, Func<Skill>> and use it to instantiate.
In the constructor:
Dictionary<Skill.Id, Func<Skill>> creationMethods = new Dictionary<Skill.Id, Func<Skill>>();
public SkillFactory()
{
creationMethods.Add(Skill.Id.FireSkill, () => new FireSkill());
creationMethods.Add(Skill.Id.WaterSkill, () => new WaterSkill());
}
Then, your Create method becomes:
public static Skill Create(Skill.Id id)
{
return creationMethods[id]();
}
Granted, this isn't much better - except that it does allow you to extend this to other functionality that's per ID without duplicating the switch block if that becomes a requirement. (Just put more into the value side of the Dictionary.)
That being said, in the long run, getting rid of the enum entirely can be a good benefit for extensibility. This will require a more elaborate change, however. For example, if you used MEF, you could import a set of SkillFactory types at runtime and associate them to a name (via metadata) via a single ImportMany. This would allow you to add new Skill subclasses without changing your factory, and refer to them by name or some other mechanism.
if this creation function is going to be so used that a "case" will produce overhead, dictionary with enums keys will generate a lot of garbage.
In the context of a xna game, it can be worse than the "case".
"If you use an enum type as a dictionary key, internal dictionary operations will cause boxing. You can avoid this by using integer keys, and casting your enum values to ints before adding them to the dictionary." Extracted from here
You can use a simple array and cast enum to int for indexing:
Enum {FireSkill=0,WaterSkill=1,etc}
Func<Skill>[] CreationMethods = new Func<Skill>()
{
() => new FireSkill(),
() => new WaterSkill(),
}
What is the best method of storing a shared object in asp.net? It will get called multiple times per request on every request. Ive been using these two methods but Id like to know if there is a better way. I refresh this object once an hour.
public static List<ResourceObject> SharedResources = new List<ResourceObject>()
//OR
public static List<ResourceObject> SharedResources
{
get
{
List<ResourceObject> _sharedResources = HttpContext.Current.Cache["RedirectRoutes"] as List<ResourceObject>;
if (_sharedResources == null)
{
_sharedResources = LoadNewSharedResource();
HttpContext.Current.Cache["RedirectRoutes"] = _sharedResources;
}
return _redirectRoutes;
}
set
{
HttpContext.Current.Cache["RedirectRoutes"] = value;
}
}
If your object is changing frequently (i.e. hourly as you mentioned) then you'll be best to use the cache as it will be able to take care of flushing for you (assuming you pass the correct parameters when adding the value to the cache). If you use a static value it will not be cleared out every hour automatically so you'd need to implement the check yourself.
If this is, as it seems, an object that needs to persist across requests, then this is a perfectly good and reasonable way to achieve it. You may want to put the cached version in a local variable if it is being accessed multiple times within one call, to save retrieving it from the cache each time.
Is there a specific issue with caching it like that that you are concerned about?
In a question about Best practices for C# pattern validation, the highest voted answer
says:
I tend to perform all of my validation in the constructor. This is a must because I almost always create immutable objects.
How exactly do you create an immutable object in C#? Do you just use the readonly keyword?
How exactly would this work if you want to validate in the constructor of your Entity Framework generated model class?
Would it look like below?
public partial readonly Person
{
public Person()
}
The interesting question here is your question from the comments:
What kind of object would you have that you do not need to modify the values at some point? I'm guessing not a model class, correct? I've had to change the name of a person in my database - this wouldn't fit with this idea.
Well, consider things that are already immutable. Numbers are immutable. Once you have the number 12, it's 12. You can't change it. If you have a variable that contains 12, you can change the contents of the variable to 13, but you are changing the variable, not the number 12.
Same with strings. "abc" is "abc", and it never changes. If you have a variable that contains "abc", you can change it to "abcd", but that doesn't change "abc", that changes the variable.
What about a list? {12, "abc"} is the list that is 12 followed by "abc", and that list never changes. The list {12, "abcd"} is a different list.
And that's where things go off the rails. Because in C# you can do it either way. You can say that there is referential identity between those two lists if lists are allowed to mutate their contents without changing their identity.
You hit the nail right on the head when you talk about the "model". Are you modeling something that changes? If so, then it is possibly wise to model it with a type that changes. The benefit of that is that the characteristics of the model match the system being modeled. The down side is that it becomes very tricky to do something like a "rollback" functionality, where you "undo" a change.
That is, if you mutate {12, "abc"} to {12, "abcd"} and then want to roll back the mutation, how do you do it? If the list is immutable you just keep around both values and choose which one you want to be the "current" value. If the list is mutable then you have to have the undo logic keep around an "undo function" which knows how to undo the mutation.
As for your specific example, you certainly can create an immutable database. How do you change the name of someone in your immutable database? You don't. You create a new database that has the data you want in it. The trick with immutable types is to do so efficiently, without copying billions of bytes. Immutable data structure design requires finding clever ways to share state between two nearly-identical structures.
Declaring all fields readonly is a good step towards creating an immutable object, but this alone is not sufficient. This is because a readonly field can still be a reference to a mutable object.
In C# immutability is not enforced by the compiler. You just have to be careful.
This question has two aspects:
Immutable type when you instantiate object
Immutable type when EF instantiate object
The first aspect demands sturcture like this:
public class MyClass
{
private readonly string _myString;
public string MyString
{
get
{
return _myString;
}
}
public MyClass(string myString)
{
// do some validation here
_myString = myString;
}
}
Now the problem - EF. EF requires parameterless constructor and EF must have setters on properties. I asked very similar question here.
Your type must look like:
public class MyClass
{
private string _myString;
public string MyString
{
get
{
return _myString;
}
private set
{
_myString = value;
}
}
public MyClass(string myString)
{
// do some validation here
_myString = myString;
}
// Not sure if you can change accessibility of constructor - I can try it later
public MyClass()
{}
}
You must also inform EF about private setter of MyString property - this is configured in properties of enitity in EDMX file. Obviously there will be no validation when EF will materialize objects from DB. Also you will not be able to use methods like ObjectContext.CreateObject (you will not be able to fill the object).
Entity Object T4 template and default code generation create factory method CreateMyClass instead of constructor with paremeters. POCO T4 template doesn't generate factory method.
I didn't try this with EF Code first.
An immutable value object is a value object that cannot be changed. You cannot modify its state, you have to create new ones
Check out Eric Lippert's blog:
Kinds of Immutability
https://learn.microsoft.com/en-us/archive/blogs/ericlippert/immutability-in-c-part-one-kinds-of-immutability
Have a look at
Immutable object pattern in C# - what do you think?
How exactly would this work if you want to validate in the constructor of your Entity Framework generated model class?
It wouldn't work in this context because EF requires the properties of the entity class be public otherwise it can't instantiate it.
But you're welcome to use immutable objects further in your code.
C# 9 is coming up with new feature names as Record. Init-only properties are great if you want to make individual properties immutable. If you want the whole object to be immutable and behave like a value, then you should consider declaring it as a record:
public data class Person
{
public string FirstName { get; init; }
public string LastName { get; init; }
}
The data keyword on the class declaration marks it as a record.
Reference: https://devblogs.microsoft.com/dotnet/welcome-to-c-9-0/#records
#Eric Lippert Good comment, but in addition in answer to the question:
What kind of object would you have that you do not need to modify the
values at some point? I'm guessing not a model class, correct? I've
had to change the name of a person in my database - this wouldn't fit
with this idea.
Let's say you have a large datastructure and you want to query its information, but it's changing all the time. You need some kind of locking system to make sure that you don't say try and count the total in the system while somebody is depositing something from one place to another. (Say a warehouse management system)
And that's hard to do because these things always affect things in unexpected ways, the data changing under your feet.
What if you could freeze your large datastructure when you're not updating it, so that no memory can be altered and it is paused at a consistent state? Now when you want to change it again you have to copy the datastructure to a new place, and it's fairly large, so that's a downside, but the upside is you won't have to lock anything because the new copy of the data goes unshared until it has been updated. This means anyone at any point can read the latest copy of the datastructure, doing complex things.
So yep very useful concept if you hate dealing with concurrency issues and don't have too much data to deal with. (E.g. if 1MB of data and updating 10/sec that's 10MB of data being copied)
I've got an ASP.Net project that uses session state, I'd like to be a little more strict about how we access session state, I'm not happy about all the strings floating around the code. I also need to know when a particular value is stored/updated in session state for tracking that object's latest value.
The string issue is easy to solve using constants, but it doesn't help with the tracking. Encapsulating them all in a single class is appealing, but then I have to pass the session object to that class, and that seems a little messy
I'm thinking of using one of two options:
Extension getters and setters on the session object
An extension method on the session object to return a class with the getters and setters
The first gives me the syntax:
var thing = Session.GetThing();
Session.SetThing(thing);
The second gives:
var thing = Session.Wrapper().Thing;
Session.Wrapper().Thing = thing;
Both have their appeal, though I'm leaning towards the second. In an ideal world I'd like to be able to do this:
var thing = Session.Thing(); // easy to do
Session.Thing() = thing; // don't think it's possible
What's the preferred way of handling this? Any of these, another way, or am I just doing it wrong?
You don't have to pass the Session to each class, you can have:
public class State
{
public string Something
{
get { return HttpContext.Current.Session["Something"] as string; }
set { HttpContext.Current.Session["Something"] = value; }
}
}
This, I believe, is the typical approach. HttpContext has the Current property which is statically available.
My preferred method is to put all of the variables that need access into an object. Then I put a variable in our page's base class that provides the appropriate access to the object in the session. The only manner of true enforcement of this is to provide a standard that requires usage of this object and then code/peer review to ensure that miscellaneous strings/variables don't end up clogging the session up.