Related
In a method that is so long that it scrolls off the screen. Just to make life easier as I program, if I want to refer to the variables of a class I can use the Me or this objects depending on which language I am using.
eg. Me.var1 = "Hello"
Is there an object (like Me) that would allow easy reference to the parameters of a function?
eg. params.par1 = "World"
There's no such feature in the language. Local variables and method arguments are treated specially by the .NET jitter, they are heavily optimized at runtime. Anything .NET would do, or you would do, to capture those variables would defeat such optimizations.
A very simple solution is to use Window + Split, it gives you two views on your code. Scroll the top one to the method header, write your code in the bottom one. You can adjust the splitter to give you more room in the bottom window.
Taking advantage of IntelliSense would be another way. Prefix the argument names with a little string, like "par". Then typing "par" in your code automatically gives you the list of argument names in the IntelliSense popup window.
These are however but band-aids for the real problem. As soon as you find yourself reaching like this, your first thought should be to split up the code in the function to make it smaller. There are some hard truths I discovered after thirty years of coding:
Long methods have more bugs. There's a metric for this, called "cyclomatic complexity". The higher the number, the more likely that the code is broken. Well supported by Visual Studio, this blog post is useful.
Code should never be indented more than 3 levels deep. By far the simplest way to discover that your cyclomatic complexity is getting out of hand without running a tool.
A method should never be larger than what fits on the screen. Any code that doesn't fit is a cognitive tax that produces compile errors and bugs. There's a corollary to this, programmers with big monitors create more bugs. The hard rule I use is one inspired by using DOS editors, a method should not have more than 25 lines of code.
Wide code produces a special kind of bug, the nasty kind that you can't see. Anything that's off the screen to the right is code that may have a bug that can take you a long time to discover. VB.NET is especially prone to this kind of bug since it uses end-of-line as a statement terminator. Much improved in VS2010 btw, the underscore is now optional in many cases. Always break your line to avoid this kind of bug.
Plan ahead and write maintainable code. Maintained code is never smaller than the original. If you already have trouble writing the original code then by definition you cannot maintain it. You have to start out small.
Always design first, code later. Long methods are a strong indicator of not thinking about code long enough before you start coding. In itself a strong bug inducer, in addition to writing correct code that just doesn't do the job.
The short answer is no. It seems like you are hoping to use this to distinguish between parameter scope and class scope for function parameters and fields with the same name, unfortunately you can't. Either use different naming schemes, or do the following:
public class MyClass {
private string myString;
private int myInt;
public MyClass(string myString) {
this.myString = myString;
}
public int DoStuff(int myInt) {
this.myInt += myInt;
return this.myInt;
}
}
to be really clear and avoid problems, you could change the names:
public class MyClass {
private string m_myString;
private int m_myInt;
public MyClass(string myString) {
m_myString = myString;
}
public int DoStuff(int myInt) {
m_myInt += myInt;
return m_myInt;
}
}
And you should really start by writing a test before the code, then you can check that you haven't accidentally mixed things up in your code.
Footnote
I include this as people coming to the title of this question may be looking for the following information.
While you say
Just for ease of programming - if I am a long way down in a function I would like to see what parameters there are without having to scroll up
In case you really want to look at your parameters from inside your code for other reasons then you need reflection. This is slow, and it's typical use would be to find a method, then reflect the parameters in that method. For a very comprehensive sample, see MSDN - ParameterInfo Class. The pertinent part of the code is:
foreach (MemberInfo mi in typeof(MyClass).GetMembers() )
{
// If the member is a method, display information about its parameters.
if (mi.MemberType==MemberTypes.Method)
{
foreach ( ParameterInfo pi in ((MethodInfo) mi).GetParameters() )
{
Console.WriteLine("Parameter: Type={0}, Name={1}", pi.ParameterType, pi.Name);
}
}
You should be able to use GetParameters() reflection method
MethodInfo barMI = bar.GetMethod("Foo");
ParameterInfo[] pars = barMI.GetParameters();
foreach (ParameterInfo p in pars)
{
Console.WriteLine(p.Name);
}
You can use this in run time. But for your aim, I would try to refactor the number of functions and their names. I try to keep code length under 80 symbols per line and the number of lines in a class under 100. Which is not always possible, but it's a good objective to decouple stuff and keep classes simple.
A simple way would be to encapsulate your parameters in an object so you can just refer to that, and intellitype (or whatever predictive feature) would show you what properties you have available without having to scroll back up. Like this
public class MyParamObject{
public string FirstParam {get;set;}
public string SecondParam {get;set;}
}
Then you could change your method from
public void MyReallyOvergrownMethod(string firstParam, string secondParam){...
to
public void MyReallyOvergrownMethod(MyParamObject params){...
then you can use the params parameter like this in the method
//Deep inside the method
if(params.FirstParam == "SomeValue"{//Do something
This is a numpty solution to a problem that would be best solved by refactoring your method. Look at loops, and conditionals and get them out into seperate private methods that are named after what they do. Loads of stuff on this, if you search for cleancoders.
In light of your comment "Just for ease of programming - if I am a long way down in a function I would like to see what parameters there are without having to scroll up": in Visual Studio, with code showing, just above the scrollbar there is a little bit you can grab and pull down to split the window. You can then have your function declaration visible in one pane and scroll as much as you like in the other. Or you can use Window menu->Split.
I've been developing .net console applications using C# and have always just dictated what order parameters must be inserted in so that args[0] is always start date and args[1] is always end date, for example.
however I would like to move over to using named parameters so that any combination of parameters can be sent in any order, such as the typical "-sd" would prefix a start date.
I know I could parse through the args[] looking for "-" and then read the name and look the next position for the accompanying value, but before doing that wanted to see if there was any kind of baked in handling for this rather standard practice.
is there something like this out there already that could do as such:
DateTime startDate = (DateTime)((ConsoleParameters)args[])["sd"]
I'm using C# and .Net 4
There is nothing built into the core framework.
A lot of people think NDesk.Options is useful for this sort of thing. Check out this example (taken directly from the provided link):
string data = null;
bool help = false;
int verbose = 0;
var p = new OptionSet () {
{ "file=", v => data = v },
{ "v|verbose", v => { ++verbose } },
{ "h|?|help", v => help = v != null },
};
List<string> extra = p.Parse (args);
Yes, the "magic" is that this is a common problem and it has been adequately solved. So I recommend using an already written library to handle parsing command line arguments.
CommandLineParser has been great for me. It is reasonably documented and flexible enough for every type of command line argument I've wanted to handle. Plus, it assists with usage documentation.
I will say that I'm not the biggest fan of making a specific class that has to be adorned with attributes to use this library, but it's a minor point considering that it solves my problem. And in reality forcing that attributed class pushes me to keep that class separate from where my app actually retrieves it's settings from and that always seems to be a better design.
You can use NDesk.Options.
There is no such a thing as named parameters. "-sd" is just a choice for a specific application. It can be "/sd" as well. Or "sd=". Or whatever you want.
Since there are no named parameters, there is nothing inside .NET Framework which let you use the "-sd" syntax.
But you can quite easily build your own method to get a set of "named parameters" for your app.
Edit: or, even better, you can use an existing library, like suggested in other answers.
Edit: reading the answer by #Sander Rijken, I see that I was wrong: there were still an implementation of "-sd" syntax in .NET 4.0 before the release. But since it was dropped before the final release, the only ways are still to create your own method or to use an existing library.
I am making an instructional video for C# 4.0 for beginning programmers.
For every topic I introduce I include a practical example which the student could actually use, for instance, for the improved COM Interop functionality, I show how to create an Excel file and fill it with values from code.
For named and option parameters I show how you can create a logging method with 5 parameters but don't have to pass any if you don't want since they all have default values. So they see how calling methods is easier with this feature.
I would also like to introduce tuples as well if I can, but it seems that all the "practical examples" (as in this question: Practical example where Tuple can be used in .Net 4.0?) are very advanced. The learners that use the video learn OOP, LINQ, using generics, etc. but e.g. functional programming or "solving Problem 11 of Project Euler" are beyond the scope of this video.
Can anyone think of an example where tuples would actually be useful to a beginning programmer or some example where they could at least understand how they could be used by and advanced programmer? Their mechanics are quite straight-forward for a beginning programmer to grasp, I would just like to find an example so that the learner could actually use them for a practical reason. Any ideas?
Here's what I have so far, but it is just dry mechanics without any functionality:
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//two ways to define them
var customer = new Tuple<int, string, string>(23, "Sam", "Smith");
var customer2 = Tuple.Create<int, string, string>(34, "James", "Allard");
//with type inference, more concise (only available with the Create keyword)
var customer3 = Tuple.Create(23, "John", "Hoopes");
//you can go up to eight, then you have to send in another tuple
var customer4 = Tuple.Create(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9, 10));
Console.WriteLine(customer.Item1);
Console.WriteLine(customer2.Item2);
Console.WriteLine(customer3.Item3);
Console.WriteLine(customer4.Rest.Item1.Item3);
Console.ReadLine();
}
}
}
Tuples are not necessarily the first topic I would tackle for beginner programmers ... however, there are some simple examples.
One that comes to mind is returning a value (which may actually be null) from a function that performs a search (or calculation), together with a boolean that indicates whether the result was found or not. It's an approach that avoids using out parameters, which can be cumbersome or problematic in certain scenarios (like LINQ queries):
public Tuple<string,bool> SearchDictionary( string searchKey )
{
string value;
bool wasFound = someDictionary.TryGetValue( searchKey, out value );
return new Tuple<string,bool( value, wasFound );
}
// since <null> is a legal value to store in the dictionary, we cannot
// use it to distinguish between 'value not found' and 'value is null'.
// the Tuple<string,bool>, however, does allow us to do so...
var result = SearchDictionary( "somekey" );
if( result.Item2 )
{
Console.WriteLine( result.Item1 );
}
Another example that I think is natural, is creating associations between two values without creating an explicit class for the purpose. For example, let's imagine we want to represent pairs of opponents who will play tennis matches. We could use:
// note the symmetry in the representation of opponents of a tennis match...
// if the relationship were asymmetrical, tuple may not be the best choice.
var playerA = new TennisPlayer("Serena Williams");
var playerB = new TennisPlayer("Venessa Williams");
var match = new Tuple<TennisPlayer,TennisPlayer>( playerA, playerB );
Creating a class for something like this can be avoided by using tuples instead.
A final example, is using tuples to represent composite keys in a dictionary. Since Tuple<>s can be compared to one another for equality, it becomes possible to do stuff like:
var complexDictionary =
new Dictionary<Tuple<string,int,decimal,DateTime>,string>();
complexDictionary.Add( new Tuple("USA",-4,1.671,DateTime.Now), "active" );
EDIT: One comment I would make when educating developers about the use of tuples, is that tuples should rarely (if ever) appear in the public interface of code you expect others to consume. As tools to simplify the internal implementation of a class or module, I think they're fine. But once you start passing them in or out of methods that developers consuming your code have to interact with, you run in the problem that tuples obscure the semantics of your API. It becomes hard for developers to interpret what Tuple<int,int> is supposed to mean. What do Item1 or Item2 mean in such a case? When you see yourself needing to pass tuples in or out of methods, you should strongly consider writing a class to encapsulate and clarify the relationship.
The best practical reason i can see is using them as temporary "classes". You want to associate multiple pieces of information, but not create yet another class structure to hold them.
They should be temporary, because if you're using them a lot, you should be going all the way and properly creating classes...
I can't think of a good specific example, i've mostly used them for small things, like temporary maps that need a single key but multiple pieces of information in the value...
I use them in place of private classes. The are great when used internally in a class.
Exposing them outside the class only led to confusion. I kept having to open the class to determine what was what.
What about on a login form? They see those all of the time.
var loginCredentials =
new Tuple<string, SecureString>(nameTextBox.Text, passwordTextBox.Text);
if (Login(loginCredentials))
Console.Writeline("Login - Success!");
else
Console.Writeline("Login - Failure");
...
public bool Login(Tuple<string, SecureString> loginCredentials)
{
return ...
}
A co-worker of mine came up with this and I wonder what others think? Personally, I find it interesting but wonder if it is too big a departure? Code examples below. Extension methods at the bottom.
General thoughts please. Other extension methods that could be added?
var ddl = Page.FindControl("LocationDropDownList") as DropDownList;
ddl.Visible = true;
ddl.SelectedValue = "123";
if(isAdmin)
ddl .SelectedValue = "111";
Becomes:
Page.FindControl("LocationDropDownList")
.CastAs<DropDownList>()
.With(d => d.Visible = true)
.With(d => d.SelectedValue = "123")
.WithIf(isAdmin, d => d.Items.Add(new ListItem("Admin", "1")));
Or:
Page.FindControl("LocationDropDownList")
.CastAs<DropDownList>()
.With(d =>
{
d.Visible = true;
d.SelectedValue = "123";
})
.WithIf(isAdmin, d => d.SelectedValue = "111");
Extension methods:
public static TResult CastAs<TResult>(this object obj) where TResult : class
{
return obj as TResult;
}
public static T With<T>(this T t, Action<T> action)
{
if (action == null)
throw new ArgumentNullException("action");
action(t);
return t;
}
public static T WithIf<T>(this T t, bool condition, Action<T> action)
{
if (action == null)
throw new ArgumentNullException("action");
if (condition)
action(t);
return t;
}
Amongst my rules of thumb for writing clear code is: put all side effects in statements; non-statement expressions should have no side effects.
Your first version of the program clearly follows this rule. The second version clearly violates it.
An additional thought: if I were to read code like the code you've displayed, I would naturally assume that the purpose of the code was to build up a lazily-evaluated structure which represented those operations -- this is exactly why query comprehensions in C# 3 are built in this way. The result of the query expression is an object representing the deferred application of the query.
If your intention is to capture the notion of "execute these side effects in a deferred manner at a later moment of my choosing", then this is a sensible approach. Essentially what you're building up is a side-effecting monad. If your intention is merely to provide a different syntax for the eagerly executed code, then this is just confusing, verbose and unnecessary.
I see no advantage to this besides being confusing to the reader. With respect to my fellow answerer, I would like to know on what planet this is more readable. As far as I can tell, the first version has more or less perfect readability, whereas this is fairly readable, but makes the reader wonder whether there's some strange magic happening within With and WithIf.
Compared to the first version, it's longer, harder to type, less obvious, and less performant.
I guess I fail to see what the new versions get you. The original is pretty clear and is less wordy. I would guess that it would be faster as well. I would avoid using (abusing?) language features like this unless there is a clear benefit.
One more vote for "not useful". The With extension method doesn't do anything except wrap up sequenced statements with a method. C# already already has a built-in function for sequencing statements, its called ;.
Similarly, the WithIf wraps an if-statement without any modification to the control flow. From my point of view, you're only inviting yourself to methods like:
public static T For<T>(
this T t, int start, Func<int, bool> cond, Action<T, int> f)
{
for(int i = start; cond(i); i++)
{
f(t, i);
}
return t;
}
The original is more readable.
The simplest API change would be to make the object returned by FindControl() a Builder-esque thing (where all the set methods return 'this'):
Page.FindControl("LocationDropDownList")
.setVisible(true)
.setSelectedValue(isAdmin ? "111" : "123");
That is some extension method abuse if I ever saw it!
It's an interesting use of extensions, and I appreciate it on that merit alone. I'm not sure I'd use it, but if your team likes it, then by all means, use it.
They're just different coding styles, what do you mean by "too big a departure"? Departure from what? From what you're used to? Only you can decide that. I will say that VB's With block has done more harm than good to code readability, and I would not try to replicate the behavior in C#, but that's just my preference.
I pretty much always use this for FindControl (yeah, strongly typed to RepeaterItem, it doesn't have to be, but that's the only thing I ever use it for anyway):
public static T FindControl<T>(this RepeaterItem item, string id)
{
return item.FindControl(id) as T;
}
And invoke it like so:
Literal myLiteral = e.Item.FindControl<Literal>("myLiteral");
I am more comfortable with the first version. It takes less time to read and understand. I agree that the extension methods are also fine if you are familiar with it and also familiar with the With method, but what’s the benefit of it in this case?
Minor note. From personal experience, I'd change:
if(isAdmin)
ddl.SelectedValue = "111";
to
if(isAdmin) {
ddl.SelectedValue = "111";
}
or
if(isAdmin)
{
ddl.SelectedValue = "111";
}
This will save you time in debugging sooner or later.
If this was a language feature:
With(Page.FindControl("LocationDropDownList") as DropDownList)
{
Visible = true;
SelectedValue = "123";
if(isAdmin)
Add(new ListItem( "111"));
}
You would win something:
avoid redundancy of the mutated object
all language features available in the "With" block
Above tries to emulate the style without reaping the benefits. Cargo Cult.
(Note: I do understand the various arguments against it, but It'd still be nice)
Incidentally, some of my C++ Win32 UI Helpers contain setters that use chaining similar what you want to achieve:
LVItem(m_lc, idx).SetText(_T("Hello")).SetImg(12).SetLParam(id);
In that case, I least win the "no redundancy", but that's because I don't have properties.
I predict the whole "fluent interface" fad will be the "hungarian notation" of the 2000's. I personally think it doesn't look very clean and it runs the risk of becoming very inconsistent if you have multiple developers each with their own preference.
Looks like your co worker is a Lambda Junkie.
I think the question of readability is subjective and I personally have no issue with what you've done. I would consider using it if your organization "approved" it.
I think the concept is sound and if you changed "With" to "Let" it would be more "functional" or "F#-ish". Personal opinion.
Page.FindControl("LocationDropDownList")
.CastAs<DropDownList>()
.Let(d => d.Visible = true)
.Let(d => d.SelectedValue = "123");
My 2 cents: It looks fine, my only comment is that "With" kind of implies something like "Where" or "Having" when you are actually setting a property. I'd suggest a method name of something like "Do", "Execute" or "Set" but maybe thats just my odd world view.
How about:
Page.WithControl<DropDownList>("LocationDropDownList")
.Do(d => d.Visible = true)
.Do(d => d.SelectedValue = "123")
.DoIf(isAdmin, d => d.Items.Add(new ListItem("Admin", "1")));
I'd say stick with the first version. What you've posted is too clever to be immediately useful to someone reading the code.
You could even go a step further and do away with that "var":
DropDownList ddl = (DropDownList) Page.FindControl("ddlName");
This is a perfect learning case on how to make something more complicated than it needs to be.
The first version is clear and requires no extra knowledge beyond normal language contructs.
I say stick with the first version without the extension methods or lamba expressions. These are relatively new concepts so not many developers will have a handle on them yet outside their use in data retrieval/manipulation from a database. If you use them you may have a hit on maintenance cost. It is nice to say "read up if this is Greek to you"; but in real-life that may be the best approach.
Regarding a "Fluent Interface" C# already has a great syntax for initializers which is (IMHO) better that trying to use the fluent style. Of course, in your example you are not initializing an new object, you are changing an existing one. My whole expertise with Fluent interfaces comes from a 30 second scan of wikipedia, but I think that JeeBee's answer is more in the spirit of Fluent programming, though I might change things slightly:
Page.FindDropDownList("LocationDropDownList")
.setVisible(true)
.setAdminSelectedValue("111")
.setSelectedValue("123")
One could argue that this is more readable, especially for a language without Properties, but I still think it doesn't make sense in C#.
In certain circumstances thoughtfully constructed fluent interfaces can be very useful. First, because the developer is presented with a limited number of options they are (typically) easy to use correctly and difficult to use incorrectly. Second, because of the sentence like structure they can be a nice clean way to declare your intentions, especially when building complex objects.
I have found fluent interfaces to be very useful when developing test code in which it is often necessary to build lots of domain objects with slight variations. I have also used them successfully as a way to introduce the decorator pattern and to eliminate excessive method overloading.
If anyone is interested in learning more about fluent interfaces, I suggest checking out this work in progress by Martin Fowler.
Good rule of thumb:
If your first impression of your code is "This is clever" - it's probably not a good idea.
Good code should be simple, readable, and only "clever" if absolutely necessary.
"Fluent interfaces" is a fairly hot topic these days. C# 3.0 has some nice features (particularly extension methods) that help you make them.
FYI, a fluent API means that each method call returns something useful, often the same object you called the method on, so you can keep chaining things. Martin Fowler discusses it with a Java example here. The concept kooks something like this:
var myListOfPeople = new List<Person>();
var person = new Person();
person.SetFirstName("Douglas").SetLastName("Adams").SetAge(42).AddToList(myListOfPeople);
I have seen some incredibly useful fluent interfaces in C# (one example is the fluent approach for validating parameters found in an earlier StackOverflow question I had asked. It blew me away. It was able to give highly readable syntax for expressing parameter validation rules, and also, if there were no exceptions, it was able to avoid instantiating any objects! So for the "normal case", there was very little overhead. This one tidbit taught me a huge amount in a short time. I want to find more things like that).
So, I'd like to learn more by looking at and discussing some excellent examples. So, what are some excellent fluent interfaces you've made or seen in C#, and what made them so valuable?
Thanks.
This is actually the first time I've heard the term "fluent interface." But the two examples that come to mind are LINQ and immutable collections.
Under the covers LINQ is a series of methods, most of which are extension methods, which take at least one IEnumerable and return another IEnumerable. This allows for very powerful method chaining
var query = someCollection.Where(x => !x.IsBad).Select(x => x.Property1);
Immutable types, and more specifically collections have a very similar pattern. Immutable Collections return a new collection for what would be normally a mutating operation. So building up a collection often turns into a series of chained method calls.
var array = ImmutableCollection<int>.Empty.Add(42).Add(13).Add(12);
Kudos for the method parameter validation, you've given me a new idea for our fluent APIs. I've hated our precondition checks anyways...
I've built a extensibility system for a new product in development, where you can fluently describe the commands available, the user interface elements and more. This runs on top of StructureMap and FluentNHibernate, which are nice APIs too.
MenuBarController mb;
// ...
mb.Add(Resources.FileMenu, x =>
{
x.Executes(CommandNames.File);
x.Menu
.AddButton(Resources.FileNewCommandImage, Resources.FileNew, Resources.FileNewTip, y => y.Executes(CommandNames.FileNew))
.AddButton(null, Resources.FileOpen, Resources.FileOpenTip, y =>
{
y.Executes(CommandNames.FileOpen);
y.Menu
.AddButton(Resources.FileOpenFileCommandImage, Resources.OpenFromFile, Resources.OpenFromFileTop, z => z.Executes(CommandNames.FileOpenFile))
.AddButton(Resources.FileOpenRecordCommandImage, Resources.OpenRecord, Resources.OpenRecordTip, z => z.Executes(CommandNames.FileOpenRecord));
})
.AddSeperator()
.AddButton(null, Resources.FileClose, Resources.FileCloseTip, y => y.Executes(CommandNames.FileClose))
.AddSeperator();
// ...
});
And you can configure all commands available like this:
Command(CommandNames.File)
.Is<DummyCommand>()
.AlwaysEnabled();
Command(CommandNames.FileNew)
.Bind(Shortcut.CtrlN)
.Is<FileNewCommand>()
.Enable(WorkspaceStatusProviderNames.DocumentFactoryRegistered);
Command(CommandNames.FileSave)
.Bind(Shortcut.CtrlS)
.Enable(WorkspaceStatusProviderNames.DocumentOpen)
.Is<FileSaveCommand>();
Command(CommandNames.FileSaveAs)
.Bind(Shortcut.CtrlShiftS)
.Enable(WorkspaceStatusProviderNames.DocumentOpen)
.Is<FileSaveAsCommand>();
Command(CommandNames.FileOpen)
.Is<FileOpenCommand>()
.Enable(WorkspaceStatusProviderNames.DocumentFactoryRegistered);
Command(CommandNames.FileOpenFile)
.Bind(Shortcut.CtrlO)
.Is<FileOpenFileCommand>()
.Enable(WorkspaceStatusProviderNames.DocumentFactoryRegistered);
Command(CommandNames.FileOpenRecord)
.Bind(Shortcut.CtrlShiftO)
.Is<FileOpenRecordCommand>()
.Enable(WorkspaceStatusProviderNames.DocumentFactoryRegistered);
Our view configure their controls for the standard edit menu commands using a service given to them by the workspace, where they just tell it to observe them:
Workspace
.Observe(control1)
.Observe(control2)
If the user tabs to the controls, the workspace automatically gets an appropriate adapter for the control and provides undo/redo and clipboard operations.
It has helped us reduce the setup code dramatically and make it even more readable.
I forgot to tell about a library we're using in our WinForms MVP model presenters to validate the views: FluentValidation. Really easy, really testable, really nice!
I love the fluent interface in CuttingEdge.Conditions.
From their sample:
// Check all preconditions:
id.Requires("id")
.IsNotNull() // throws ArgumentNullException on failure
.IsInRange(1, 999) // ArgumentOutOfRangeException on failure
.IsNotEqualTo(128); // throws ArgumentException on failure
I've found that it is a lot easier to read, and makes me much more effective at checking my preconditions (and post conditions) in methods than when I have 50 if statements to handle the same checks.
Here's one I made just yesterday. Further thought may lead me to change the approach, but even if so, the "fluent" approach let me accomplish something I otherwise could not have.
First, some background. I recently learned (here on StackOverflow) a way to pass a value to a method such that the method would be able to determine both the name and the value. For example, one common use is for parameter validation. For example:
public void SomeMethod(Invoice lastMonthsInvoice)
{
Helper.MustNotBeNull( ()=> lastMonthsInvoice);
}
Note there's no string containing "lastMonthsInvoice", which is good because strings suck for refactoring. However, the error message can say something like "The parameter 'lastMonthsInvoice' must not be null." Here's the post that explains why this works and points to the guy's blog post.
But that is just background. I'm using the same concept, but in a different way. I am writing some unit tests, and I want to dump certain property values out to the console so they show up in the unit test output. I got tired of writing this:
Console.WriteLine("The property 'lastMonthsInvoice' has the value: " + lastMonthsInvoice.ToString());
... because I have to name the property as a string and then refer to it. So I made it where I could type this:
ConsoleHelper.WriteProperty( ()=> lastMonthsInvoice );
And get this output:
Property [lastMonthsInvoice] is: <whatever ToString from Invoice
produces>
Now, here's where a fluent approach allowed me to do something I otherwise couldn't do.
I wanted to make ConsoleHelper.WriteProperty take a params array, so it could dump many such property values to the console. To do that, its signature would look like this:
public static void WriteProperty<T>(params Expression<Func<T>>[] expr)
So I could do this:
ConsoleHelper.WriteProperty( ()=> lastMonthsInvoice, ()=> firstName, ()=> lastName );
However, that doesn't work due to type inference. In other words, all of these expressions do not return the same type. lastMonthsInvoice is an Invoice. firstName and lastName are strings. They cannot be used in the same call to WriteProperty, because T is not the same across all of them.
This is where the fluent approach came to the rescue. I made WriteProperty() return something. The type it returned is something I can call And() on. This gives me this syntax:
ConsoleHelper.WriteProperty( ()=> lastMonthsInvoice)
.And( ()=> firstName)
.And( ()=> lastName);
This is a case where the fluent approach allowed something that otherwise would not have been possible (or at least not convenient).
Here's the full implementation. As I said, I wrote it yesterday. You'll probably see room for improvement or maybe even better approaches. I welcome that.
public static class ConsoleHelper
{
// code where idea came from ...
//public static void IsNotNull<T>(Expression<Func<T>> expr)
//{
// // expression value != default of T
// if (!expr.Compile()().Equals(default(T)))
// return;
// var param = (MemberExpression)expr.Body;
// throw new ArgumentNullException(param.Member.Name);
//}
public static PropertyWriter WriteProperty<T>(Expression<Func<T>> expr)
{
var param = (MemberExpression)expr.Body;
Console.WriteLine("Property [" + param.Member.Name + "] = " + expr.Compile()());
return null;
}
public static PropertyWriter And<T>(this PropertyWriter ignored, Expression<Func<T>> expr)
{
ConsoleHelper.WriteProperty(expr);
return null;
}
public static void Blank(this PropertyWriter ignored)
{
Console.WriteLine();
}
}
public class PropertyWriter
{
/// <summary>
/// It is not even possible to instantiate this class. It exists solely for hanging extension methods off.
/// </summary>
private PropertyWriter() { }
}
In addition to the ones specified here, the popuplar RhinoMocks unit test mock framework uses fluent syntax to specify expectations on mock objects:
// Expect mock.FooBar method to be called with any paramter and have it invoke some method
Expect.Call(() => mock.FooBar(null))
.IgnoreArguments()
.WhenCalled(someCallbackHere);
// Tell mock.Baz property to return 5:
SetupResult.For(mock.Baz).Return(5);
Method Naming
Fluent interfaces lend themselves to readability as long as the method names are chosen sensibly.
With that in mind, I'd like to nominate this particular API as "anti-fluent":
System.Type.IsInstanceOfType
It's a member of System.Type and takes an object, and returns true if the object is an instance of the type. Unfortunately, you naturally tend to read it from left to right like this:
o.IsInstanceOfType(t); // wrong
When it's actually the other way:
t.IsInstanceOfType(o); // right, but counter-intuitive
But not all methods could possibly be named (or positioned in the BCL) to anticipate how they might appear in "pseudo-English" code, so this isn't really a criticism. I'm just pointing out another aspect of fluent interfaces - the choosing of method names in order to cause the least surprise.
Object Initializers
With many of the examples given here, the only reason a fluent interface is being used is so that several properties of a newly allocated object can be initialized within a single expression.
But C# has a language feature that very often makes this unnecessary - object initializer syntax:
var myObj = new MyClass
{
SomeProperty = 5,
Another = true,
Complain = str => MessageBox.Show(str),
};
This perhaps would explain why expert C# users are less familiar with the term "fluent interface" for chaining calls on the same object - it isn't needed quite so often in C#.
As properties can have hand-coded setters, this is an opportunity to call several methods on the newly constructed object, without having to make each method return the same object.
The limitations are:
A property setter can only accept one argument
A property setter cannot be generic
I would like it if we could call methods and enlist in events, as well as assign to properties, inside an object initializer block.
var myObj = new MyClass
{
SomeProperty = 5,
Another = true,
Complain = str => MessageBox.Show(str),
DoSomething()
Click += (se, ev) => MessageBox.Show("Clicked!"),
};
And why should such a block of modifications only be applicable immediately after construction? We could have:
myObj with
{
SomeProperty = 5,
Another = true,
Complain = str => MessageBox.Show(str),
DoSomething(),
Click += (se, ev) => MessageBox.Show("Clicked!"),
}
The with would be a new keyword that operates on an object of some type and produces the same object and type - note that this would be an expression, not a statement. So it would exactly capture the idea of chaining in a "fluent interface".
So you could use initializer-style syntax regardless of whether you'd got the object from a new expression or from an IOC or factory method, etc.
In fact you could use with after a complete new and it would be equivalent to the current style of object initializer:
var myObj = new MyClass() with
{
SomeProperty = 5,
Another = true,
Complain = str => MessageBox.Show(str),
DoSomething(),
Click += (se, ev) => MessageBox.Show("Clicked!"),
};
And as Charlie points out in the comments:
public static T With(this T with, Action<T> action)
{
if (with != null)
action(with);
return with;
}
The above wrapper simply forces a non-returning action to return something, and hey presto - anything can be "fluent" in that sense.
Equivalent of initializer, but with event enlisting:
var myObj = new MyClass().With(w =>
{
w.SomeProperty = 5;
w.Another = true;
w.Click += (se, ev) => MessageBox.Show("Clicked!");
};
And on a factory method instead of a new:
var myObj = Factory.Alloc().With(w =>
{
w.SomeProperty = 5;
w.Another = true;
w.Click += (se, ev) => MessageBox.Show("Clicked!");
};
I couldn't resist giving it the "maybe monad"-style check for null as well, so if you have something that might return null, you can still apply With to it and then check it for null-ness.
SubSonic 2.1 has a decent one for the query API:
DB.Select()
.From<User>()
.Where(User.UserIdColumn).IsEqualTo(1)
.ExecuteSingle<User>();
tweetsharp makes extensive use of a fluent API too:
var twitter = FluentTwitter.CreateRequest()
.Configuration.CacheUntil(2.Minutes().FromNow())
.Statuses().OnPublicTimeline().AsJson();
And Fluent NHibernate is all the rage lately:
public class CatMap : ClassMap<Cat>
{
public CatMap()
{
Id(x => x.Id);
Map(x => x.Name)
.WithLengthOf(16)
.Not.Nullable();
Map(x => x.Sex);
References(x => x.Mate);
HasMany(x => x.Kittens);
}
}
Ninject uses them too, but I couldn't find an example quickly.
I wrote a little fluent wrapper for System.Net.Mail which I find makes it email code much more readable (and easier to remember the syntax).
var email = Email
.From("john#email.com")
.To("bob#email.com", "bob")
.Subject("hows it going bob")
.Body("yo dawg, sup?");
//send normally
email.Send();
//send asynchronously
email.SendAsync(MailDeliveredCallback);
http://lukencode.com/2010/04/11/fluent-email-in-net/
The Criteria API in NHibernate has a nice fluent interface which allows you to do cool stuff like this:
Session.CreateCriteria(typeof(Entity))
.Add(Restrictions.Eq("EntityId", entityId))
.CreateAlias("Address", "Address")
.Add(Restrictions.Le("Address.StartDate", effectiveDate))
.Add(Restrictions.Disjunction()
.Add(Restrictions.IsNull("Address.EndDate"))
.Add(Restrictions.Ge("Address.EndDate", effectiveDate)))
.UniqueResult<Entity>();
The new HttpClient of the WCF REST Starter Kit Preview 2 is a great fluent API. see my blog post for a sample http://bendewey.wordpress.com/2009/03/14/connecting-to-live-search-using-the-httpclient/
As #John Sheehan mentioned, Ninject uses this type of API to specify bindings. Here are some example code from their user guide:
Bind<IWeapon>().To<Sword>();
Bind<Samurai>().ToSelf();
Bind<Shogun>().ToSelf().Using<SingletonBehavior>();