Optional Design Pattern, Advantages [closed] - c#

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
So, it's pretty well known that the infamous NullReferenceException is the most common exception in software products. I've been reading some articles, and found myself with the Optional approach.
Its aim is to create some kind of encapsulation around a nullable value
public sealed class Optional<T> where T : class {
private T value;
private Optional(T value) {
this.value = value;
}
//Used to create an empty container
public static Optional<T> Empty() {
return new Optional(null);
}
//Used to create a container with a non-null value
public static Optional<T> For(T value) {
return new Optional(value);
}
//Used to check if the container holds a non-null value
public bool IsPresent {
get { return value != null; }
}
//Retrieves the non-null value
public T Value {
get { return value; }
}
}
Afterwards, the now optional value can be returned like this:
public Optional<ICustomer> FindCustomerByName(string name)
{
ICustomer customer = null;
// Code to find the customer in database
if(customer != null) {
return Optional.Of(customer);
} else {
return Optional.Empty();
}
}
And handled like this:
Optional<ICustomer> optionalCustomer = repository.FindCustomerByName("Matt");
if(optionalCustomer.IsPresent) {
ICustomer foundCustomer = optionalCustomer.Value;
Console.WriteLine("Customer found: " + customer.ToString());
} else {
Console.WriteLine("Customer not found");
}
I don't see any improvement, just shifted complexity.
The programmer must remember to check if a value IsPresent, in the same way he must remember to check if a value != null.
And if he forgets, he would get a NullReferenceException on both approaches.
What am I missing? What advantages (if any) does the Optional pattern provide over something like Nullable<T> and the null coalescing operator?

Free your mind
If you think of Option as Nullable by a different name then you are absolutely correct - Option is simply Nullable for reference types.
The Option pattern makes more sense if you view it as a monad or as a specialized collection that contain either one or zero values.
Option as a collection
Consider a simple foreach loop with a list that cannot be null:
public void DoWork<T>(List<T> someList) {
foreach (var el in someList) {
Console.WriteLine(el);
}
}
If you pass an empty list to DoWork, nothing happens:
DoWork(new List<int>());
If you pass a list with one or more elements in it, work happens:
DoWork(new List<int>(1));
// 1
Let's alias the empty list to None and the list with one entry in it to Some:
var None = new List<int>();
var Some = new List(1);
We can pass these variables to DoWork and we get the same behavior as before:
DoWork(None);
DoWork(Some);
// 1
Of course, we can also use LINQ extension methods:
Some.Where(x => x > 0).Select(x => x * 2);
// List(2)
// Some -> Transform Function(s) -> another Some
None.Where(x => x > 0).Select(x => x * 2);
// List()
// None -> None
Some.Where(x => x > 100).Select(x => x * 2);
// List() aka None
// Some -> A Transform that eliminates the element -> None
Interesting side note: LINQ is monadic.
Wait, what just happened?
By wrapping the value that we want inside a list we were suddenly able to only apply an operation to the value if we actually had a value in the first place!
Extending Optional
With that consideration in mind, let's add a few methods to Optional to let us work with it as if it were a collection (alternately, we could make it a specialized version of IEnumerable that only allows one entry):
// map makes it easy to work with pure functions
public Optional<TOut> Map<TIn, TOut>(Func<TIn, TOut> f) where TIn : T {
return IsPresent ? Optional.For(f(value)) : Empty();
}
// foreach is for side-effects
public Optional<T> Foreach(Action<T> f) {
if (IsPresent) f(value);
return this;
}
// getOrElse for defaults
public T GetOrElse(Func<T> f) {
return IsPresent ? value : f();
}
public T GetOrElse(T defaultValue) { return IsPresent ? value: defaultValue; }
// orElse for taking actions when dealing with `None`
public void OrElse(Action<T> f) { if (!IsPresent) f(); }
Then your code becomes:
Optional<ICustomer> optionalCustomer = repository.FindCustomerByName("Matt");
optionalCustomer
.Foreach(customer =>
Console.WriteLine("Customer found: " + customer.ToString()))
.OrElse(() => Console.WriteLine("Customer not found"));
Not much savings there, right? And two more anonymous functions - so why would we do this? Because, just like LINQ, it enables us to set up a chain of behavior that only executes as long as we have the input that we need. For example:
optionalCustomer
.Map(predictCustomerBehavior)
.Map(chooseIncentiveBasedOnPredictedBehavior)
.Foreach(scheduleIncentiveMessage);
Each of these actions (predictCustomerBehavior, chooseIncentiveBasedOnPredictedBehavior, scheduleIncentiveMessage) is expensive - but they will only happen if we have a customer to begin with!
It gets better though - after some study we realize that we cannot always predict customer behavior. So we change the signature of predictCustomerBehavior to return an Optional<CustomerBehaviorPrediction> and change our second Map call in the chain to FlatMap:
optionalCustomer
.FlatMap(predictCustomerBehavior)
.Map(chooseIncentiveBasedOnPredictedBehavior)
.Foreach(scheduleIncentiveMessage);
which is defined as:
public Optional<TOut> FlatMap<TIn, TOut>(Func<TIn, Optional<TOut>> f) where TIn : T {
var Optional<Optional<TOut>> result = Map(f)
return result.IsPresent ? result.value : Empty();
}
This starts to look a lot like LINQ (FlatMap -> Flatten, for example).
Further possible refinements
In order to get more utility out of Optional we should really make it implement IEnumerable. Additionally, we can take advantage of polymorphism and create two sub-types of Optional, Some and None to represent the full list and the empty list case. Then our methods can drop the IsPresent checks, making them easier to read.
TL;DR
The advantages of LINQ for expensive operations are obvious:
someList
.Where(cheapOp1)
.SkipWhile(cheapOp2)
.GroupBy(expensiveOp)
.Select(expensiveProjection);
Optional, when viewed as a collection of one or zero values provides a similar benefit (and there's no reason it couldn't implement IEnumerable so that LINQ methods would work on it as well):
someOptional
.FlatMap(expensiveOp1)
.Filter(expensiveOp2)
.GetOrElse(generateDefaultValue);
Further suggested reading
Option (F#)
When null is not enough (C#)
The neophytes guide to Scala Part 5: The Option type
The Marvel of Monads (C#)
Eric Lippert's series on LINQ and monads

it would probally make more sense if you used something like this
interface ICustomer {
String name { get; }
}
public class OptionalCustomer : ICustomer {
public OptionalCustomer (ICustomer value) {
this.value = value;
}
public static OptionalCustomer Empty() {
return new OptionalCustomer(null);
}
ICustomer value;
public String name { get {
if (value == null ) {
return "No customer found";
}
return value.Name;
}
}
}
now if your pass an "empty" optional customer object you can still call the .Name property (without getting nullpointers)

The advantage of Optional is you know if something may not exist.
The problem with many types of queries that return a null is that that could mean 2 things:
The query didn't return a result
The query returned a result whose value was null.
I know you're asking specifically about C# but Java just introduced Optionals in Java 8 so there are a lot of articles about it so I'll use Java as an example. but it's completely the same idea as in C#:
Consider the Java Map.get(key) method
Object value = map.get(key);
if(value ==null){
//is there an entry in the map key =>null or does key not exist?
}
to get around that you have to have an additional method containsKey( k)
With optional, you only need one method
Optional<Object> result = map.get(key);
if(result.isPresent()){
Object value = result.get();
//if value is null, then we know that key =>null
}
More info see this Java article : http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html

Did you mean: Null Object pattern
The article linked to me in the comments contains a conclusion section explained this programming tool.
... The purpose of Optional is not to replace every single null reference in your codebase but rather to help design better APIs in which—just by reading the signature of a method—users can tell whether to expect an optional value. .... deal with the absence of a value; as a result, you protect your code against unintended null pointer exceptions.
Anyway, let it crash and find the reason. If you do not want endlessly embedded if statements than use an implementation pattern Guard Clause pattern, which says the following:
While programs have a main flow, some situations require deviations from the
main flow. The guard clause is a way to express simple and local exceptional
situations with purely local consequences.

Related

Converting non-nullable expression to nullable without hard typing/casting in linq queries

I regularly find myself coding things like
int? min = someQueryable
.Where(x => someCondition)
.Select(x => (int?)x.someNonNullableIntProperty)
.Min();
It allows me to get null instead of "System.ArgumentNullException: value cannot be null" when nothing matches the condition. (And I do not want to get 0 instead of null.)
I would like to avoid the cast. Is there any other way I have missed?
The hard part is, it should be of sufficiently common use to be natively understood (or ignored) by linq providers. (linq-to-entities and linq-to-nhibernate for my specific needs.)
Otherwise I would have to add some custom AsNullable extensions to linq-to-nh provider (which requires some work), and I do not know if EF (6) allows to do this.
Why do I wish avoiding cast? Casting may go unnoticed during refactoring, and then may cause bugs. And most of the cast I see in code are due to careless developers, not trying to memorize they can have the non-null value from .Value on nullable types, by example. (There is also the ternary case like someCondition ? someIntProperty : (int?)null but the "Elvis" operator ?. will probably allow to avoid most of them ; and we can also write default(int?), althougth it is a bit lengthy. ?. could maybe even be used for my example query, but it would not be a general solution.)
Trying new Nullable<int>(x.someNonNullableIntProperty) as suggested here fails with a NotSupportedException (with NH, not tested with EF). Anyway, it would not suit me either. In case of some later type change of the property, it may go unnoticed too due to implicit conversion. (And trying new Nullable(x.someNonNullableIntProperty) does not compile, generic type argument inferring does not work well with constructors.)
Trying x.someNonNullableIntProperty as int? (which is still a cast, but less tolerant about types mismatch in this case, see this here) fails with an ArgumentException (NH tested again, Expression of type 'System.Int32' cannot be used as a 'System.Nullable`1[System.Int32]' return type (translated)).
I tried this once, but for IEnumerable, and came up with
public static T? max<T>(IEnumerable<T> values) where T: struct, IComparable<T>
{
T? result = null;
foreach (var v in values)
if (!result.HasValue || (v.CompareTo(result.Value) > 0))
result = v;
return result;
}
To handle IQueryable, you'd need to extend your data access library. In case of NHibernate, the mechanism is called HqlGenerator. See this answer for links.
For Entity Framework, I have given up. It looks as too much effort for me. (See here.)
For NHibernate, I have done the AsNullable extension I was thinking of.
This is following the same logic as my other extensions here and here.
First, define an AsNullable extension:
public static class NullableExtensions
{
public static T? AsNullable<T>(this T value) where T : struct
{
// Allow runtime use.
// Not useful for linq-to-nhibernate, could be:
// throw NotSupportedException();
return value;
}
}
Then, implements its HQL translation (originally based on NHibernate compare implementation, then quite simplified, see edits):
public class AsNullableGenerator : BaseHqlGeneratorForMethod
{
public AsNullableGenerator()
{
SupportedMethods = new[]
{
ReflectionHelper.GetMethodDefinition(() => NullableExtensions.AsNullable(0))
};
}
public override HqlTreeNode BuildHql(MethodInfo method,
Expression targetObject,
ReadOnlyCollection<Expression> arguments,
HqlTreeBuilder treeBuilder,
IHqlExpressionVisitor visitor)
{
// Just have to transmit the argument "as is", HQL does not need a specific call
// for null conversion.
return visitor.Visit(arguments[0]).AsExpression();
}
}
Extend the default linq2NH registry with your generator:
public class ExtendedLinqToHqlGeneratorsRegistry :
DefaultLinqToHqlGeneratorsRegistry
{
public ExtendedLinqToHqlGeneratorsRegistry()
: base()
{
this.Merge(new AsNullableGenerator());
}
}
Now configure NH to use your new registry. With hibernate.cfg.xml, add following property node under session-factory node:
<property name="linqtohql.generatorsregistry">YourNameSpace.ExtendedLinqToHqlGeneratorsRegistry, YourAssemblyName</property>
Or using code:
using NHibernate.Cfg;
// ...
var cfg = new Configuration();
cfg.LinqToHqlGeneratorsRegistry<ExtendedLinqToHqlGeneratorsRegistry>();
// And build the session factory using this configuration.
Now we can rewrite the query.
int? min = someQueryable
.Where(x => someCondition)
.Select(x => x.someNonNullableIntProperty.AsNullable())
.Min();

Why is my getter being called until there is a StackOverflow? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I use a generic list in my Winforms app, and had code throughout where I would first check if the underlying (json) file existed and, if it did, deserialize it, and then access the deserialized generic list. I decided it would be better to put that code in one place, so did this:
public static List<AssignmentHistory> assignmentHistList
{
get { return GetAssignmentHistoryList(); }
}
public static List<AssignmentHistory> GetAssignmentHistoryList()
{
if (!System.IO.File.Exists(ASSIGNMENT_HISTORY_FILENAME)) return null;
if (null == assignmentHistList)
{
return DeserializeAssignmentHistFile();
}
return assignmentHistList;
}
public static List<AssignmentHistory> DeserializeAssignmentHistFile()
{
var assignmentHistFile = System.IO.File.ReadAllText(ASSIGNMENT_HISTORY_FILENAME);
var assignmentHistDeserialized = JsonConvert.DeserializeObject<List<AssignmentHistory>>(assignmentHist);
return assignmentHistDeserialized;
}
I then call it like so:
AssignmentHistory ah =
AYttFMConstsAndUtils.assignmentHistList.FirstOrDefault(
i => i.WeekOfAssignment == currentWeek && i.TalkType == 1);
...but never get beyond that line, as GetAssignmentHistoryList() gets called over and over again until there is a stack overflow. What am I doing wrong here?
UPDATE
I used abto's null coalescing operator suggestion, but to prevent against the possibility of an empty file, I had to also modify my Deserialize method, so that it is now:
private static List<AssignmentHistory> DeserializeAssignmentHistFile()
{
List<AssignmentHistory> assignmentHistoryList;
if (!System.IO.File.Exists(ASSIGNMENT_HISTORY_FILENAME))
{
var assignmentFile = System.IO.File.Create(ASSIGNMENT_HISTORY_FILENAME);
assignmentFile.Close();
}
var assignmentHistFile = System.IO.File.ReadAllText(ASSIGNMENT_HISTORY_FILENAME);
var assignmentHistDeserialized = JsonConvert.DeserializeObject<List<AssignmentHistory>>(assignmentHistFile);
if (null != assignmentHistDeserialized) return assignmentHistDeserialized;
assignmentHistoryList = new List<AssignmentHistory>();
return assignmentHistoryList;
}
Because there are already answers why your code fails, I wanted to post a possible fix to your code:
// this is the backing field for your property
private static List<AssignmentHistory> assignmentHistList;
// it is good practice to name properties starting uppercase
public static List<AssignmentHistory> AssignmentHistList
{
get
{
// return the content of the backing field if is not null
return assignmentHistList ??
// in case the backing field is null,
// assign it a value from your deserialize method
// and than return it
(assignmentHistList = DeserializeAssignmentHistFile());
}
}
private static List<AssignmentHistory> DeserializeAssignmentHistFile()
{
// If the file which should contain your data does not exist (yet) return null,
// the property will retry to set the backing field the next time it is accessed
if (!System.IO.File.Exists(ASSIGNMENT_HISTORY_FILENAME)) return null;
var assignmentHistFile
= System.IO.File.ReadAllText(ASSIGNMENT_HISTORY_FILENAME);
var assignmentHistDeserialized
= JsonConvert.DeserializeObject<List<AssignmentHistory>>(assignmentHist);
return assignmentHistDeserialized;
}
Then you can call it (mostly) like you wanted:
AssignmentHistory ah = AYttFMConstsAndUtils.AssignmentHistList
.FirstOrDefault(i => i.WeekOfAssignment == currentWeek && i.TalkType == 1);
Remember that this will throw an ArgumentNullException if the file from which should be deserialized does not exist.
Label1:
The assignmentHistList property's getter invokes GetAssignmentHistoryList() which recursively invokes assignmentHistList property's getter.
goto Label1;
You might have wanted the property to be called AssignmentHistList with upper-case A, in-line with the common code style practice, and having a private static field assignmentHistList. Anyway, the duality of existence of a property X and a GetX() method is wierd.
Stackoverflow exceptions usually occur due to Recursive call condition that was not detected right.
Only by observing the following code, we can deduce their is a visious circular calls.
assignmentHistList -> GetAssignmentHistoryList, which checks the condition null == assignmentHistList but in order to check this condition it needs to enter (Recursion) for assignmentHistList again, which will then call GetAssignmentHistoryList again.. And you can see where this is going.
public static List<AssignmentHistory> assignmentHistList
{
get { return GetAssignmentHistoryList(); }
}
public static List<AssignmentHistory> GetAssignmentHistoryList()
{
if (!System.IO.File.Exists(ASSIGNMENT_HISTORY_FILENAME)) return null;
if (null == assignmentHistList) << Here is another call to the Getter
// The rest is not important
}

What is the purpose of nameof?

Version 6.0 got a new feature of nameof, but I can't understand the purpose of it, as it just takes the variable name and changes it to a string on compilation.
I thought it might have some purpose when using <T> but when I try to nameof(T) it just prints me a T instead of the used type.
Any idea on the purpose?
What about cases where you want to reuse the name of a property, for example when throwing exception based on a property name, or handling a PropertyChanged event. There are numerous cases where you would want to have the name of the property.
Take this example:
switch (e.PropertyName)
{
case nameof(SomeProperty):
{ break; }
// opposed to
case "SomeOtherProperty":
{ break; }
}
In the first case, renaming SomeProperty will cause a compilation error if you don't change both the property definition and the nameof(SomeProperty) expression. In the second case, renaming SomeOtherProperty or altering the "SomeOtherProperty" string will result in silently broken runtime behavior, with no error or warning at build time.
This is a very useful way to keep your code compiling and bug free (sort-of).
(A very nice article from Eric Lippert why infoof didn't make it, while nameof did)
It's really useful for ArgumentException and its derivatives:
public string DoSomething(string input)
{
if(input == null)
{
throw new ArgumentNullException(nameof(input));
}
...
Now if someone refactors the name of the input parameter the exception will be kept up to date too.
It is also useful in some places where previously reflection had to be used to get the names of properties or parameters.
In your example nameof(T) gets the name of the type parameter - this can be useful too:
throw new ArgumentException(nameof(T), $"Type {typeof(T)} does not support this method.");
Another use of nameof is for enums - usually if you want the string name of an enum you use .ToString():
enum MyEnum { ... FooBar = 7 ... }
Console.WriteLine(MyEnum.FooBar.ToString());
> "FooBar"
This is actually relatively slow as .Net holds the enum value (i.e. 7) and finds the name at run time.
Instead use nameof:
Console.WriteLine(nameof(MyEnum.FooBar))
> "FooBar"
Now .Net replaces the enum name with a string at compile time.
Yet another use is for things like INotifyPropertyChanged and logging - in both cases you want the name of the member that you're calling to be passed to another method:
// Property with notify of change
public int Foo
{
get { return this.foo; }
set
{
this.foo = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.Foo));
}
}
Or...
// Write a log, audit or trace for the method called
void DoSomething(... params ...)
{
Log(nameof(DoSomething), "Message....");
}
Another use-case where nameof feature of C# 6.0 becomes handy - Consider a library like Dapper which makes DB retrievals much easier. Albeit this is a great library, you need to hardcode property/field names within query. What this means is that if you decide to rename your property/field, there are high chances that you will forget to update query to use new field names. With string interpolation and nameof features, code becomes much easier to maintain and typesafe.
From the example given in link
without nameof
var dog = connection.Query<Dog>(
"select Age = #Age, Id = #Id",
new {Age = (int?) null, Id = guid});
with nameof
var dog = connection.Query<Dog>(
$"select {nameof(Dog.Age)} = #Age, {nameof(Dog.Id)} = #Id",
new {Age = (int?) null, Id = guid});
Your question already expresses the purpose. You must see this might be useful for logging or throwing exceptions.
For example:
public void DoStuff(object input)
{
if (input == null)
{
throw new ArgumentNullException(nameof(input));
}
}
This is good. If I change the name of the variable, the code will break instead of returning an exception with an incorrect message.
Of course, the uses are not limited to this simple situation. You can use nameof whenever it would be useful to code the name of a variable or property.
The uses are manifold when you consider various binding and reflection situations. It's an excellent way to bring what were run time errors to compile time.
The most common use case I can think of is when working with the INotifyPropertyChanged interface. (Basically everything related to WPF and bindings uses this interface)
Take a look at this example:
public class Model : INotifyPropertyChanged
{
// From the INotifyPropertyChanged interface
public event PropertyChangedEventHandler PropertyChanged;
private string foo;
public String Foo
{
get { return this.foo; }
set
{
this.foo = value;
// Old code:
PropertyChanged(this, new PropertyChangedEventArgs("Foo"));
// New Code:
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Foo)));
}
}
}
As you can see in the old way we have to pass a string to indicate which property has changed. With nameof we can use the name of the property directly. This might not seem like a big deal. But image what happens when somebody changes the name of the property Foo. When using a string the binding will stop working, but the compiler will not warn you. When using nameof you get a compiler error that there is no property/argument with the name Foo.
Note that some frameworks use some reflection magic to get the name of the property, but now we have nameof this is no longer neccesary.
Most common usage will be in input validation, such as
//Currently
void Foo(string par) {
if (par == null) throw new ArgumentNullException("par");
}
//C# 6 nameof
void Foo(string par) {
if (par == null) throw new ArgumentNullException(nameof(par));
}
In first case, if you refactor the method changing par parameter's name, you'll probably forget to change that in the ArgumentNullException. With nameof you don't have to worry about that.
See also: nameof (C# and Visual Basic Reference)
The ASP.NET Core MVC project uses nameof in the AccountController.cs and ManageController.cs with the RedirectToAction method to reference an action in the controller.
Example:
return RedirectToAction(nameof(HomeController.Index), "Home");
This translates to:
return RedirectToAction("Index", "Home");
and takes takes the user to the 'Index' action in the 'Home' controller, i.e. /Home/Index.
Let's say you need to print the name of a variable in your code. If you write:
int myVar = 10;
print("myVar" + " value is " + myVar.toString());
and then if someone refactors the code and uses another name for myVar, he/she would have to look for the string value in your code and change it accordingly.
Instead, if you write:
print(nameof(myVar) + " value is " + myVar.toString());
It would help to refactor automatically!
The MSDN article lists MVC routing (the example that really clicked the concept for me) among several others. The (formatted) description paragraph reads:
When reporting errors in code,
hooking up model-view-controller (MVC) links,
firing property changed events, etc.,
you often want to
capture the string name of a method. Using nameof helps keep your code
valid when renaming definitions.
Before you had to use string literals
to refer to definitions, which is brittle when renaming code elements
because tools do not know to check these string literals.
The accepted / top rated answers already give several excellent concrete examples.
As others have already pointed out, the nameof operator does insert the name that the element was given in the sourcecode.
I would like to add that this is a really good idea in terms of refactoring since it makes this string refactoring safe. Previously, I used a static method which utilized reflection for the same purpose, but that has a runtime performance impact. The nameof operator has no runtime performance impact; it does its work at compile time. If you take a look at the MSIL code you will find the string embedded. See the following method and its disassembled code.
static void Main(string[] args)
{
Console.WriteLine(nameof(args));
Console.WriteLine("regular text");
}
// striped nops from the listing
IL_0001 ldstr args
IL_0006 call System.Void System.Console::WriteLine(System.String)
IL_000C ldstr regular text
IL_0011 call System.Void System.Console::WriteLine(System.String)
IL_0017 ret
However, that can be a drawback if you plan to obfuscate your software. After obfuscation the embedded string may no longer match the name of the element. Mechanisms that rely on this text will break. Examples for that, including but not limited to are: Reflection, NotifyPropertyChanged ...
Determining the name during runtime costs some performance, but is safe for obfuscation. If obfuscation is neither required nor planned, I would recommend using the nameof operator.
The purpose of the nameof operator is to provide the source name of the artifacts.
Usually the source name is the same name as the metadata name:
public void M(string p)
{
if (p == null)
{
throw new ArgumentNullException(nameof(p));
}
...
}
public int P
{
get
{
return p;
}
set
{
p = value;
NotifyPropertyChanged(nameof(P));
}
}
But this may not always be the case:
using i = System.Int32;
...
Console.WriteLine(nameof(i)); // prints "i"
Or:
public static string Extension<T>(this T t)
{
return nameof(T); returns "T"
}
One use I've been giving to it is for naming resources:
[Display(
ResourceType = typeof(Resources),
Name = nameof(Resources.Title_Name),
ShortName = nameof(Resources.Title_ShortName),
Description = nameof(Resources.Title_Description),
Prompt = nameof(Resources.Title_Prompt))]
The fact is that, in this case, I didn't even need the generated properties to access the resources, but now I have a compile time check that the resources exist.
The purpose of nameof is refactoring. For example when you change the name of a class to which you refer to through nameof somewhere else in your code you will get a compilation error which is what you want. If you didn't use nameof and had just a plain string as a reference you'd have to fulltext search for the name of the class in order to change it. That's a pain in the bottom. With nameof you can rest easy, build, and get all the cases for change automatically in your IDE.
Another use case of nameof is to check tab pages, instead of checking the index you can check the Name property of the tabpages as follow:
if(tabControl.SelectedTab.Name == nameof(tabSettings))
{
// Do something
}
Less messy :)
I find that nameof increases the readability of very long and complex SQL statements in my applications. It makes the variables stand out of that sea of strings and eliminates your job of figuring out where the variables are used in your SQL statements.
public bool IsFooAFoo(string foo, string bar)
{
var aVeryLongAndComplexQuery = $#"SELECT yada, yada
-- long query in here
WHERE fooColumn = #{nameof(foo)}
AND barColumn = #{nameof(bar)}
-- long query here";
SqlParameter[] parameters = {
new SqlParameter(nameof(foo), SqlDBType.VarChar, 10){ Value = foo },
new SqlParameter(nameof(bar), SqlDBType.VarChar, 10){ Value = bar },
}
}
One of the usage of nameof keyword is for setting Binding in wpf programmatically.
to set Binding you have to set Path with string, and with nameof keyword, it's possible to use Refactor option.
For example, if you have IsEnable dependency property in your UserControl and you want to bind it to IsEnable of some CheckBox in your UserControl, you can use these two codes:
CheckBox chk = new CheckBox();
Binding bnd = new Binding ("IsEnable") { Source = this };
chk.SetBinding(IsEnabledProperty, bnd);
and
CheckBox chk = new CheckBox();
Binding bnd = new Binding (nameof (IsEnable)) { Source = this };
chk.SetBinding(IsEnabledProperty, bnd);
It's obvious the first code can't refactor but the secend one...
Previously we were using something like that:
// Some form.
SetFieldReadOnly( () => Entity.UserName );
...
// Base form.
private void SetFieldReadOnly(Expression<Func<object>> property)
{
var propName = GetPropNameFromExpr(property);
SetFieldsReadOnly(propName);
}
private void SetFieldReadOnly(string propertyName)
{
...
}
Reason - compile time safety. No one can silently rename property and break code logic. Now we can use nameof().
It has advantage when you use ASP.Net MVC. When you use HTML helper to build some control in view it uses property names in name attribure of html input:
#Html.TextBoxFor(m => m.CanBeRenamed)
It makes something like that:
<input type="text" name="CanBeRenamed" />
So now, if you need to validate your property in Validate method you can do this:
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
if (IsNotValid(CanBeRenamed)) {
yield return new ValidationResult(
$"Property {nameof(CanBeRenamed)} is not valid",
new [] { $"{nameof(CanBeRenamed)}" })
}
}
In case if you rename you property using refactoring tools, your validation will not be broken.

Convert loop to Maybe monad

Recently I tried applying Maybe monad pattern in my C# code using this library.
What I found difficult to grasp was converting such a function into Maybe paradigm:
public Maybe<object> DoSomething(IReader reader)
{
while (true)
{
var result = reader.Read();
if (result == null) return Maybe<object>.Nothing;
if (result.HasValue) return new Maybe<object>(null);
}
}
I would like to have it written using from x in X form. The functionality that stands behind this function is to read IReader until it returns a value (Maybe has a value) or an error occurs (null gets returned).
the answer to your comment/question is: you don't - yeah you could try it using recursive calls but this might fail horrible in C# and you are way better of with the while
from x in X is just the monadic - bind (it get's translated into the SelectMany functions) and there is just no direct way in the LINQ syntax for this.
But you can write your own function like this:
public tValue DoUntilSome<tValue>(Func<Maybe<tValue>> f)
{
while (true)
{
var x = f();
if (x.HasValue) return x.Value;
}
}
and call like (see below)
var result = DoUntilSome(() => TryRead(reader));
remarks
first the Maybe<object> (object) part is a smell - because you most certainly want a concrete type in there instead of the generic object
Then new Maybe<object>(null) is very strange too
I would have suggested something like:
public Maybe<tValue> TryRead<tValue>(IReader reader)
{
var result = reader.Read();
if (result == null || !result.HasValue)
return Maybe<tValue>.Nothing;
return new Maybe<tValue>((tValue)reader.Value);
}
then of course this part is there to get some Maybe value - the thing you are trying to do with from x in X is the monadic-bind - which you can only use once you have a Maybe to start with:
from value in TryRead<tValue>(reader)
from other in TrySomethingDifferent(value) // here is the bind
select ....
disclaimer
I did not compile any of this (because I was to lazy to download the github project and stuff) - put you should be able to easily solve any syntax errors that might hide there - sorry for that
In case you have major troubles just leave a comment

Efficient way of initializing a generic class' fields and/or properties

I am writing a ConfigParser class, which reads from a config file structured like this:
[Section]
option1 = foo
option2 = 12
option3 = ;
...
The information read is actually stored in a Dictionary<string, string>. What i'd like to achieve is the following:
struct ConfigStruct
{
public string option1;
public int option2;
public char option3 { get; set; }
// Any other _public_ fields or properties
}
ConfigParser Cp = new ConfigParser("path/to/config/file"); // Loads content
ConfigStruct Cs = Cp.CreateInstance<ConfigStruct>("Section");
Console.WriteLine(Cs.option1); // foo
Console.WriteLine(Cs.option2.ToString()); // 12
Console.WriteLine(Cs.option3.ToString()); // ;
The struct (or class, it doesn't matter) ConfigStruct, is application-specific, and the ConfigParser class should know nothing about it. Basically, I want to parse the value from a specific option, and store it into the field/property with the same name. Parsing should be done according to the field/property type.
I've developed a stub method for it:
public T CreateInstance<T>(string Section) where T : new()
{
// Gets options dictionary from loaded data
Dictionary<string, string> Options = this.Data[Section];
T Result = new T();
Type StructType = Result.GetType();
foreach (var Field in StructType.GetFields())
{
if (!Options.ContainsKey(Field.Name))
continue;
Object Value;
if (Field.FieldType == typeof(bool))
Value = Boolean.Parse(Options[Field.Name]);
else if (Field.FieldType == typeof(int))
Value = Int32.Parse(Options[Field.Name]);
else if (Field.FieldType == typeof(double))
Value = Double.Parse(Options[Field.Name]);
else if (Field.FieldType == typeof(string))
Value = Options[Field.Name];
else if (Field.FieldType == typeof(char))
Value = Options[Field.Name][0];
// Add any ifs if needed
else { /* Handle unsupported types */ }
Field.SetValue(Result, Value);
}
foreach (var Property in StructType.GetProperties())
{
// Do the same thing with public properties
}
return Result;
}
Do you think this is the right approach to the problem? Or should I move the responsability of initializing the struct to the application logic instead of the ConfigParser class? I know it's more efficient, but using reflection I write this method only once, and works for every struct.
Should I use reflection to invoke Parse() so that I can avoid all those ifs? Or you'd rather make those conversions type by type, to prevent unexpected behaviour?
Thanks for your time.
Assuming there is a specific reason why you are not using app.config/web.config or other built-in configuration files.
I think this comes down to what the rest of the application is doing, but personally I would do it this way. It allows you to get the return type cleanly and you are not passing an extra stuct down the stack that you don't need to be.
Reflection is a fantastic tool but has some overhead so if the list of types is finite then specifying them manually is more efficient, or alternately only reflecting the unknown types. Also I would change your if blocks to a switch statement, you will gain efficiencies if the IL complier can fully optimise the condition block.
I think there is a simpler solution. You could use a custom section handler to store your settings, custom section handlers are well described here: http://devlicio.us/blogs/derik_whittaker/archive/2006/11/13/app-config-and-custom-configuration-sections.aspx).

Categories

Resources