As the title states, I want to know the most efficient ways to invoke a lazy loaded object property. Consider the following class definition:
Class MyObject
{
private _stringList = null;
public List<string> StringList
{
set
{
_stringList = value;
}
get
{
if(_stringList == null)
{
_stringList = new List<string>();
//fill the List with strings from some data source
}
return _stringList;
}
}
}
Now I want to pre-load StringList with the most in-expensive operation, what whould that be?
MyObject obj = new MyObject();
obj.StringList.ToString(); //?
obj.StringList.Count(); //?
obj.StringList.Equals(null); //?
What about:
if(obj.StringList == null){}
I don't like this method but it seems like it would be less expensive than calling a method on the property.
I'm looking for an answer specific to List as well as a generic object.
EDIT: I understand that this is considered a micro optimization but that is not the point of the question. I'm not asking if you like what I'm suggesting doing here. I want to know the best way to do this relative to CPU and/or memory usage and some proof that the suggested method is actually better than others.
I also think that tis kind of optimization is not relevant, but i guess the "best" would be
var someVar = obj.StringList;
Just invoke the getter. You may get a warning since you have an unused variable, but you can suppress this warning with a pragma...
But as Sergey already mentioned, in that case it does not make sense to implement lazy load...
I believe comparison with null is the less expensive way. But I would not care of such micro optimization (if you are loading data from file or database, then all these options is nothing comparing to IO operations). Also if you want to pre-load data, then you don't need lazy-loading. Main point of lazy-loading is to defer data loading until you really will need that data.
UPDATE: If you really want to pre-load data for properties, I suggest you to make it in more explicit way. Otherwise other developers will guess why you are comparing properties with null or setting them to local variables which are not used. Create some method in your class which will clearly show your intent:
MyObject obj = new MyObject();
obj.Load(); // or Initialize()
This is classic example of lazy loading. Also note that using setter is defeating purpose of your example because if every client can reset your list then every client must take care of the loading - this is not so good
Class MyObject
{
private List<string> _stringList = null;
public List<string> StringList
{
get
{
if(_stringList == null)
{
_stringList = new List<string>();
//fill the List with strings from some data source
}
return _stringList;
}
}
}
On another note, if you use List.Count > 0, the optimization for this will be Linq List.Any
Related
Having these enums
ReportType, ReportField and ReportDimension with the following specification:
Basically I have three report types and each one is kind of unique, one supports some of the ReportFields and some of the ReportDimensions (doesn't matter which), I would like to create a dictionary that has 3 KeyValuePair items (for every report type) and has tuple as value that looks like this:
private readonly Dictionary<ReportType, (List<ReportField>, List<ReportDimension>)> _reportTypeDimensionMappings;
I wanted to directly instantiate this structure but the way I intend to, gives me build errors:
private readonly Dictionary<ReportType, (List<ReportField>, List<ReportDimension>)> _reportTypeDimensionMappings = new Dictionary<ReportType,
(List<ReportField>, List<ReportDimension>)>
{
{ReportType.Session, new (List<ReportField>, List<ReportDimension>)
{
new List<ReportField>
{
},
new List<ReportDimension>
{
}
}
},
};
Is there an explicit good practice way to instantiate the value of a dictionary that's a Tuple ?
It's already been suggested that you shouldn't be using a Tuple here, and I agree, but to answer your question, the syntax is quite simple:
private readonly Dictionary<ReportType, (List<ReportField>, List<ReportDimension>)> _reportTypeDimensionMappings =
new Dictionary<ReportType, (List<ReportField>, List<ReportDimension>)>
{
{ReportType.Session, (new List<ReportField>(), new List<ReportDimension>()) }
};
It seems like a class would be better suited for what you need. You could create a class called Report that contains your List<ReportField> and List<ReportDimension> properties.
Tuples are useful for when you need a short-lived, relatively-small collection of values or objects to be treated as one thing (i.e. a return from a method), but there's really not much cost to creating a dedicated class for these types of things either. As Daniel A. White pointed out in your comments section, it makes your code harder to read, and given you don't need much of a reason to create a class for any purpose, I'd say any reason is good enough.
You can create a Tuple object by calling Tuple t = Tuple.Create(object1, object2); then you can get the values by t.Item1 for object1 and t.Item2 for object2
I am new to C#, so bear with me. I have a problem in c# where I can't decide on whether I need a class or a struct. I'm creating a List of either the class or struct and adding elements to it. If I use a struct, then I can add an item, alter it, and add it again and the changes will be seen because it is passed by value. The problem is, structs are not mutable so I can't edit any of the elements later. If I use a class, then if I add an item and alter it, all the items in the list get changed. I have to create a new instance of the object each time if I want it to be different. But I have an object that I only want to change one item in, so I have to copy all the other items to the new object?! WHY? Is there a better solution?
This code illustrates my problem:
namespace TestError
{
public partial class Form1 : Form
{
private List<Thing> lst;
private Thing obj;
public Form1()
{
InitializeComponent();
lst = new List<Thing>();
obj = new Thing();
obj.a = "bla";
lst.Add(obj);
//obj = new Thing();
obj.a = "thing";
lst.Add(obj);
foreach (Thing t in lst)
listBox1.Items.Add(t.a);
}
}
class Thing
{
public string a;
//problem is there are many more items here that don't change!
}
}
Why the struct doesn't work:
namespace TestError
{
public partial class Form1 : Form
{
private List<Thing> lst;
private Thing obj;
public Form1()
{
InitializeComponent();
lst = new List<Thing>();
obj = new Thing();
obj.a = "bla";
lst.Add(obj);
lst[0].a = "new"; //error. if i change it to class, it works.
obj.a = "thing";
lst.Add(obj);
foreach (Thing t in lst)
listBox1.Items.Add(t.a);
}
}
struct Thing
{
public string a;
}
}
Class is the way to go. I've never touch the struct type since I left college.
For the Thing class, you stated" there are many more items here that don't change!". Is that mean the values are fixed or the values are based on the initial object. If the values are fixed, you can assigned some default values in the class.
If the values are based on the initial object, I don't see the hassle of passing the variable while adding the object to the list.
The problem is, structs are not mutable so I can't edit any of the elements later.
This is simply not true; don't get me wrong, I think it is a really bad idea to do what you are trying to here, and I think a class with a Clone() method would be the best solution, but the reason you are thinking this is precisely due to value-type semantics. You need to keep in mind that list indexers (the [0]) are methods - and not direct access; consider:
lst[0].a = "new";
what this line would do, if it compiled, is:
fetch a copy of the object out of the list (this is now a completely isolated and separate copy)
change a field on the copy
discard the copy
The compiler knows that this pretty certainly is not what you intended, so it prevents you making a mistake; the usage there would be:
var tmp = lst[0];
tmp.a = "new";
lst[0].a = tmp;
Oddly enough, though - if lst were an array, then that would work - arrays allow for direct in-situ editing:
lst[0].a = "new";
would compile. HOWEVER, PLEASE DON'T DO THIS:
mutable structs are a bad idea and will cause lots of confusion in your code
public fields are also a bad idea
large structs are also a bad idea
Like I say, my advice here would be a class; if you want convenient copy semantics, then add a Clone() method
Say I have a List<Objects>. I want to define the list of objects in one method, and use them in several others.
Here's the ways I've come up with and I'm looking for more or the correct way to do it.
You can define List<Objects> in every method that uses it.
Pros: It works. No chance of getting the wrong variable.
Cons: Code duplication.
You can use a private List<Objects> defined in the class and update it using (ref ListObjects)
Pros: I only have to define it once.
Cons: I feel like it's messy and bad practice.
You can pass List<Objects> as a parameter to the methods that use it.
Pros: Prevents code duplication
Cons: Have to make my populate functions return functions, and add parameters to my other methods. Possible conflicts with Events?
So that's what I've come up with. I'm really not sure which to use or if there's a better way to do this. Thoughts?
EDIT: Including some code as requested.
private List<MedicalPlan> medicalPlansList;
This is the list. It is a list that gets information from a database, here:
private void BindMedicalList()
{
medicalPlansList = new MedicalPlanRepository().RetrieveAll().Where(x => x.Year == year).ToList();
}
Then it's used to find objects in that list, such as
var result =
medicalPlansList.FirstOrDefault(
c => c.CoverageLevels.Any(p => p.Id == id));
This is, in general, how I'd do it. If you always use the same sequence of functions on a list, consider creating a chained function to handle that. You can also directly pass a function call inside one of the other function calls (as long as it returns a list), but that tends to look messy.
public List<int> DoSomethingWithList(List<int> list)
{
//do stuff
return list;
}
public List<int> DoSomethingElseWithList(List<int> list)
{
//do other stuff
return list;
}
public void SomeOtherFunction(string[] args)
{
var list = new List<int>() { 1, 2, 3, 4 }; //create list
list = DoSomethingWithList(list); //change list
list = DoSomethingElseWithList(list); //change list further
}
If you are working with an object that has a List<T> field, I'd do like this:
public class MyBigClass
{
private List<int> myList;
public MyBigClass()
{
//instantiate list in constructor
myList = new List<int>() { 1, 2, 3, 4 };
}
public void PublicListAdder(int val)
{
myList.Add(val);
}
private void PrivateListCleaner()
{
//remove all even numbers, just an example
myList.RemoveAll(x => x % 2 == 0);
}
}
You rarely need to use ref in C#, because it automatically handles pointers for you. You are (usually) not passing around a struct, you are passing around an object reference (which basically is a pointer).
Your #1 and #2 don't really make sense:
If you define a different list in every method that uses it, then you're using a different list each time. This is not sharing the list; this doesn't work. If you mean "call your method that creates the list from each method that uses it" then the same still applies: you're using a different list each time.
You don't need to use ref ListObjects to update a private member; a private member is just accessed by its name. This isn't bad practice; this is standard object-oriented practice.
Passing all required data into a method as parameters makes the method inherently more reusable as it reduces coupling to the class the method belongs to.
In short: #3 is good practice to an extent, as it increases the reusability of code. However, the use of #2 is fundamentally the reason we have Object-Oriented programming: to save you from repeatedly passing parameters into all your methods. This is exactly what private fields are designed for!
In most cases, I would probably go with Anders' answer. Depending on your situation, another way that is worth considering is to write extension methods for List.
namespace ExtensionMethods
{
public static class MyExtensions
{
public static object DoSomething(this List<T> list)
{
//do the something with list
}
}
}
And then you can use it like so:
var list = new List<int>();
list.DoSomething();
In that example, list is passed as the parameter to the extension method.
Usually a List<T> shouldn't belong to the state of an instance and exposed since it's mutable and you may change the state from the outside otherwise -unless your getter is designed to return a readonly list. Unless your design clearly allow such a possibility when it may occur. My reply doesn't really answer to your question is just a suggestion of good object oriented design. As someone already suggested much better than me you may pass a List back and forth each method and directly modify it.
I have a class with two properties, say
public class Book {
public string TitleSource { get; set; }
public string TitleTarget { get; set; }
}
I have an IList<Book> where the TitleTarget is null and for each item in the list, I need to copy the TitleSource property to the TitleTarget property. I could do this through a loop, sure, but it seems like there's a LINQ or nice declarative way to do this. Is there?
Linq was designed as a way to consume things. If you look at web discussions about why there is no IEnumerable.ForEach(...) extension, you'll see that the Linq designers purposefully avoided Linq to Object scenarios where the methods were designed to change object values.
That said, you can cheat by "selecting" values and not using the results. But, that creates items which are thrown away. So, a foreach loop is much more efficient.
Edit for people who really want something besides foreach
Another "cheat" that wouldn't produce a new list would be to use a method that does little work of it's own, like Aggregate, All, or Any.
// Return true so All will go through the whole list.
books.All(book => { book.TitleTarget = book.TitleSource; return true; });
It's not LINQ as such, but there's:
books.Where(book => book.TitleTarget == null).ToList()
.ForEach(book => book.TitleTarget = book.TitleSource);
The main point is the ToList method call: there's no ForEach extension method (I don't think?) but there is one on List<T> directly. It wouldn't be hard to write your own ForEach extension method as well.
As to whether this would be better than a simple foreach loop, I'm not so sure. I would personally choose the foreach loop, since it makes the intention (that you want to modify the collection) a bit clearer.
#John Fisher is correct, there is no IEnumerable.ForEach.
There is however a ForEach on List<T>. So you could do the following:
List<Book> books = GetBooks();
books.ForEach(b => b.TitleTarget = b.TitleSource);
If you wanted a IEnumerable.ForEach it would be easy to create one:
public static class LinqExtensions
{
public static void ForEach<TSource>(this IEnumerable<TSource> source, Action<TSource> action)
{
foreach (var item in source)
{
action(item);
}
}
}
You can then use the following snippet to perform your action across your collection:
IList<Book> books = GetBooks();
books.ForEach(b => b.TitleTarget = b.TitleSource);
If you can use .NET 4.0, and you are using a thread-safe collection then you can use the new parallel ForEach construct:
using System.Threading.Tasks;
...
Parallel.ForEach(
books.Where(book => book.TitleTarget == null),
book => book.TitleTarget = book.TitleSource);
This will queue tasks to be run on the thread pool - one task that will execute the assignment delegate for each book in the collection.
For large data sets this may give a performance boost, but for smaller sets may actually be slower, given the overhead of managing the thread synchronization.
books.Select(b => b.TitleTarget = b.TitleSource);
This doesn't create any 'new items', just a query that you won't enumerate. That doesn't seem like a big deal to me.
I was asked to explain the ugly thing and advantages of anonymous method.
I explained possibly
Ugly thing
anonymous methods turning quickly into spaghetti code.
Advantages
We can produce thread safe code using anonymous method :Example
static List<string> Names = new List<string>(
new string[] {
"Jon Skeet",
"Marc Gravell",
"David",
"Bill Gates"
});
static List<string> FindNamesStartingWith(string startingText)
{
return Names.FindAll(
delegate(string name)
{
return name.StartsWith(startingText);
});
}
But really i did not know whether it is thread safe or not.I was asked to justify it.
Can any one help me to understand
(1) advantages of anonymous methods
(2) Is the above code thread safe or not?
Well, "thread safe" is a pretty broad term. What sort of multi-threaded use are you thinking of? I'd expect it to be safe without any data corruption or exceptions if nothing's writing to the list...
Now, as for the "ugliness" of anonymous methods... are you using C# 3? If so, start using lambda expressions, which are generally cleaner:
static List<string> FindNamesStartingWith(string startingText)
{
return Names.FindAll(name => name.StartsWith(startingText));
}
Alternatively, using LINQ:
static List<string> FindNamesStartingWith(string startingText)
{
return Names.Where(name => name.StartsWith(startingText)).ToList();
}
Or if you don't necessarily need a list:
static IEnumerable<string> FindNamesStartingWith(string startingText)
{
return Names.Where(name => name.StartsWith(startingText));
}
Or if you prefer a query expression:
static IEnumerable<string> FindNamesStartingWith(string startingText)
{
return from name in names
where name.StartsWith(startingText)
select name;
}
None of these look like spaghetti code to me. However, if you're going to ask whether you should use this or something else, you should really put forward an alternative. Here's a simple one:
static List<string> FindNamesStartingWith(string startingText)
{
List<string> ret = new List<string>();
foreach (string name in Names)
{
if (name.StartsWith(startingText))
{
ret.Add(name);
}
}
return ret;
}
Do you find that clearer? If so, that's fine - but I suspect it's just that you're not really familiar with anonymous functions, LINQ etc. As you can see, there's significantly more code - it would definitely take me longer to check that that does the right thing than any of the earlier samples.
Well, it all depends on what you mean by thread-safe.
If, during the execution of FindAll, some other thread changes the underlying Names collection, then you might get odd results.
Is multiple calls to FindAll on multiple threads safe by themselves, that is, with only them executing? Yes, that's a definite yes.
As for the advantages of anonymous methods, consider the alternative.
You want to:
Find some item of the collection
The only way to know which item you want to find is to evaluate some expression for each one
You could do it like this:
List<string> result = new List<string>();
foreach (string name in Names)
if (name.StartsWith(startingText))
result.Add(name);
return result;
or, given the new lambda syntax, you could do it like this:
return Names.FindAll(name => name.StartsWith(startingText));
I know which one I prefer, but they do different things, with the same result (in this case.)
In the first case, you execute all the code yourself, there's no magic.
In the second case, you give to FindAll a way to figure out which items to put into the result. There is no non-executable way to do that in this case, you need to have FindAll execute some code, that you specify, for each item.