in

 

Jimmy Bogard

Assistant to the assistant to the regional manager

Stop creating custom delegate types

Note to OSS and framework developers:

Please stop creating custom delegate types.  Use the Action and Func delegates instead.

The problem is that delegate types with the same signature are not convertible to each other.  For example, none of these assignments will work:

public delegate bool CustomMatchingFunction(string value);

public void Custom_delegates_are_bad()
{
    Predicate<string> match1 = value => value == "Blarg";
    Func<string, bool> match2 = value => value == "Blarg";
    CustomMatchingFunction match3 = value => value == "Blarg";

    match1 = match2;
    match1 = (Predicate<string>)match2;
    match1 = match3;
}

Although all of the delegate types shown have the same signature, this does not mean that they're the same type.  They're neither implicitly nor explicitly convertible from each other.  One of the preliminary LINQ framework design guidelines states:

Do use the new LINQ types "Func<>" and "Expression<>" instead of custom delegates and predicates, when defining new APIs.

There are Action delegates for void methods and Func delegates for methods that return values.  If something needs a delegate, use either the generic or specific versions of these delegate types.  Instead of "Predicate<T>", use "Func<T, bool>".  Instead of creating a custom void delegate, use "Action".

By creating custom delegate types, you're forcing people using your API to either force your custom type into their code, or force them to use a bunch of "wrapper methods" that wrap, convert and call your custom delegate type.

If you declare even a single delegate type in your code (and you're using .NET 3.5), stop and make sure there isn't already an Action or Func delegate that works for you.

Published Mar 26 2008, 10:03 AM by bogardj
Filed under:

Comments

 

Peter Ritchie said:

...after you upgrade to Visual Studio 2008...

March 26, 2008 10:40 AM
 

Joe Ocampo said:

Nice. I am surprised R#4 doesn't catch this, in its hints.

March 26, 2008 5:34 PM
 

Jarod said:

It is a personal goal to never type the word 'delegate' in an IDE again :)

Func<>/Action<T> is kind of addicting though, they are so easy I find myself wanting to use them were I would have not considered a delegate in the past.

March 26, 2008 6:32 PM
 

bogardj said:

@Peter

Yeah yeah...let's just pretend that everyone upgrades to .NET 3.5 immediately.

I wanted to get some comments back from the FDG folks to see what they might recommend for .NET 2.0 situations...but these custom delegates can be a real pain...

March 26, 2008 7:33 PM
 

Ray Houston said:

If you&#39;re like me, you&#39;re lazy and hate putting try/catch around your transaction handling in

March 27, 2008 8:35 PM
 

Reflective Perspective - Chris Alcock » The Morning Brew #61 said:

Pingback from  Reflective Perspective - Chris Alcock  &raquo; The Morning Brew #61

March 28, 2008 3:23 AM
 

Jon Skeet said:

It's not quite as bad as you're making it out to be. Yes, there's no direct conversion - but you don't need to write any extra methods to convert from one to another. The following assignments both work:

match1 = new Predicate<string>(match2);

match1 = new Predicate<string>(match3);

No wrapper methods required.

That said, I do agree that it's best not to create your own delegate types by and large.

Jon

March 28, 2008 3:31 AM
 

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

March 28, 2008 9:38 AM
 

Bart Czernicki said:

Uhh...no.  2 reasons:

- backwards compatibility:

I could list you a few examples why u still would want custom delegate types, but say ur maintaining an API that has to work with 2.0 code...why exactly would u start using Func/Action??

Same goes for automatic properties, collection initializers, implicit anon types...all the "syntactic sugar" for C# 3.0

- standards:

The achitect should define what the best practices are and code standards are.  If you ur standards are to write code a specific way and then u have developers auto update their code to what they see on a blog, ur going to have bigger problems

March 28, 2008 3:34 PM
 

Justin Etheredge said:

Here here, that is an excellent suggestion for those working on a completely 3.5 codebase.

March 28, 2008 3:55 PM
 

bogardj said:

@Jon

Hooray!  I knew someone would find a way for it to work easily.  Thanks!

March 28, 2008 8:23 PM
 

bogardj said:

@Jon

Hooray!  I knew someone would find a way for it to work easily.  Thanks!

March 28, 2008 8:24 PM
 

bogardj said:

@Bart

Many of the C# 3.0 features work just fine with .NET 2.0.  C# 3.0 still compiles to the CLR 2.0.  It's just not as nice :)

Yes, this only applies to .NET 3.5.  It's still annoying creating these custom types, especially when you have APIs that expose properties and methods that are designed to work with Action/Func and something has to translate.

March 28, 2008 8:26 PM
 

Bart Czernicki said:

@bogardj

"many" is the keyword here.  

I completely agree that Func/Action provide u enough overrides to not have to create a delegate.  Even if, you have a method that takes 8 parameters u should be passing in an object instead probably and using a Func/Action

However, with having a mixed dev environment 2005/2008 (which we are transitioning from) it would cause MAJOR coding horrors if we had developers go on blogs and simply apply what a few people agree is a good practice.

March 28, 2008 9:00 PM
 

bogardj said:

@Bart

If you have developers applying wholesale advice from what they read on blogs, I think your problem is in the personnel/training department.

This isn't just my advice, it comes from Microsoft's Framework Design Guidelines folks as well.  It applies only to .NET 3.5 environments.

March 31, 2008 7:17 AM
 

Frank Quednau said:

Recently I encountered one issue with generic delegates: They cannot be marshalled to static external functions imported from some dll. In this case you will have to define your own non-generic delegate even though you may have a fitting one.

April 10, 2008 3:53 AM
 

Buy carisoprodol. said:

Buy carisoprodol best prices limited time offer. Buy carisoprodol.

June 20, 2008 11:05 PM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About bogardj

I'm a senior consultant with Headspring Systems in Austin, TX. My focus is using .NET technologies together with Agile methodologies. Back in 2005, I drank the Agile punch and haven't looked at a waterfall the same since.
Copyright Los Techies 2007. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems