Contents tagged with .NET
Two simple Extension Methods for Reader
I have added to my Extension Methods library a very useful ForEachLine methods, that extends the TextReader and FileInfo functionality.
The purpose of those methods is simple: provides ability to provide action to invoked for each line of a TextReader of file.Here are the methods for anyone how find them useful, as well.
TextReader ForEachLine Extension Method
public static void ForEachLine(this TextReader reader, Action<string> action) {
if (reader == null)
throw new ArgumentNullException("reader");
if (action == null)
throw new ArgumentNullException("action");
string line;
while ((line = reader.ReadLine()) != null) {
action(line);
}
}
FileInfo ForEachLine Extension Method
public static void ForEachLine(this FileInfo file, Action<string> action) {
if (file == null)
throw new ArgumentNullException("file");
using (StreamReader reader = file.OpenText()) {
reader.ForEachLine(action);
}
}
Happy coding ...
DateTime.ToSiteString() Extension Method
I'm mostly using LINQ to SQL and Entity Framework recently.
As you know, the datetime database fields are returned as Nullables of type DateTime, if they allow NULL values and I found myself adding a lot of additional data class properties like:public string ModifiedString {
get {
return this.ModifiedOn.HasValue
? this.ModifiedOn.Value.ToString("dd MMM yyyy") : "";
}
}
So, I decided to wrap that an a nice Extension Method, make it once, and then just use it.
And here is what I came up with:
namespace System {
/// <summary>
///
/// </summary>
public static class XtsDate {
#region Static Fields /////////////////////////////////////////////////////////////////////
/// <summary>
/// Gets the date format.
/// </summary>
/// <value>The date format.</value>
public static string DateFormat = "dd MMM yyyy";
#endregion
#region Static Methods ////////////////////////////////////////////////////////////////////
/// <summary>
/// Toes the site string.
/// </summary>
/// <param name="date">The date.</param>
/// <returns></returns>
public static string ToSiteString(this DateTime date) {
return date.ToString(DateFormat);
}
/// <summary>
/// Toes the site string.
/// </summary>
/// <param name="date">The date.</param>
/// <returns></returns>
public static string ToSiteString(this DateTime? date) {
return date.HasValue ? date.Value.ToString(DateFormat) : "";
}
#endregion
}
}
Now, when I need some DateTime field as string I just can use:
return this.ModifiedOn.ToSiteString();
Hope this helps anyone ...
Regards
The laziest property lazy-initialization
Today I want to revue the history of property lazy-initialization I used over the years.
Further more, I decided to "measure" if I'm changing for good and is the pattern I use last is the best, the most optimized one.First, in the old good years I used the "standard" lazy-initialization pattern:
public string First {
get {
if (_first == null) {
_first = "Initialized";
}
return _first;
}
}
Then, at some point I realized I could use by my opinion better pattern:
public string Second {
get {
return (_second != null) ? _second : (_second = "Initialized");
}
}
Last, I found out the good usage of "??" operator on property lazy-initialization and here is my latest pattern:
public string Last {
get {
return _last ?? (_last = "Initialized");
}
}
So, in code the last one looks better, shorter and more optimized like.
But, is that the real case. I decided to check out the generated IL and here are the results:First :
.method public hidebysig specialname instance string
get_First() cil managed
{
// Code size 41 (0x29)
.maxstack 2
.locals init ([0] string CS$1$0000,
[1] bool CS$4$0001)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld string Artem.WebSite.Models.Test::_first
IL_0007: ldnull
IL_0008: ceq
IL_000a: ldc.i4.0
IL_000b: ceq
IL_000d: stloc.1
IL_000e: ldloc.1
IL_000f: brtrue.s IL_001e
IL_0011: nop
IL_0012: ldarg.0
IL_0013: ldstr "Initialized"
IL_0018: stfld string Artem.WebSite.Models.Test::_first
IL_001d: nop
IL_001e: ldarg.0
IL_001f: ldfld string Artem.WebSite.Models.Test::_first
IL_0024: stloc.0
IL_0025: br.s IL_0027
IL_0027: ldloc.0
IL_0028: ret
} // end of method Test::get_First
Second:
.method public hidebysig specialname instance string
get_Second() cil managed
{
// Code size 36 (0x24)
.maxstack 3
.locals init ([0] string CS$1$0000,
[1] string CS$0$0001)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld string Artem.WebSite.Models.Test::_second
IL_0007: brtrue.s IL_0019
IL_0009: ldarg.0
IL_000a: ldstr "Initialized"
IL_000f: dup
IL_0010: stloc.1
IL_0011: stfld string Artem.WebSite.Models.Test::_second
IL_0016: ldloc.1
IL_0017: br.s IL_001f
IL_0019: ldarg.0
IL_001a: ldfld string Artem.WebSite.Models.Test::_second
IL_001f: stloc.0
IL_0020: br.s IL_0022
IL_0022: ldloc.0
IL_0023: ret
} // end of method Test::get_Second
Last:
.method public hidebysig specialname instance string
get_Last() cil managed
{
// Code size 30 (0x1e)
.maxstack 3
.locals init ([0] string CS$1$0000,
[1] string CS$0$0001)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld string Artem.WebSite.Models.Test::_last
IL_0007: dup
IL_0008: brtrue.s IL_0019
IL_000a: pop
IL_000b: ldarg.0
IL_000c: ldstr "Initialized"
IL_0011: dup
IL_0012: stloc.1
IL_0013: stfld string Artem.WebSite.Models.Test::_last
IL_0018: ldloc.1
IL_0019: stloc.0
IL_001a: br.s IL_001c
IL_001c: ldloc.0
IL_001d: ret
} // end of method Test::get_Last
Less lines in IL for every next pattern, which should means better and more optimized code.
Great. I'm happy now and I'm sure my lazy-initialization pattern has changed for goodHope this helps...
Regards