In Case You Haven’t Heard


It has been a while since I have posted.  We have been working hard to get Orcas beta 1 and beta 2 done.  So I apologize for the long interlude between posts but I hope that you are enjoying beta 1 and that you are looking forward to beta 2.

Now that beta 1 is out there, what do you all think of it?  Beta 1 has most of the features that we intend to put into Orcas but not all of them.  Some notable differences you will see in later releases are improved performance, error messages, error recovery, stability, and a few refinements.  Basically the kind of polish that people expect as a product nears completion.

Partial Methods

One feature that you may have not heard of yet is a feature called partial methods.  This is some of the work that I did in the last coding milestone a few months back.  Partial methods are methods that enable lightweight event handling.  Here is an example declaration:

partial class C
{
  static partial void M(int i);
}

There are a few notable things here:

1.  Partial methods must be declared within partial classes

2.  Partial methods are indicated by the partial modifier

3.  Partial methods do not always have a body (well look at this more below)

4.  Partial methods must return void

5.  Partial methods can be static

6.  Partial methods can have arguments (including this, ref, and params modifiers)

7.  Partial methods must be private

Now suppose that I make a call to C.M.

partial class C
{

  static void Main()
  {
    C.M(Calculation());
  }
}

Since M has no body, all calls to C.M are removed at compile time as well as the evaluation of the arguments.  So the above program is equivalent to:

partial class C
{

  static void Main()
  {
  }
}

In this sense, partial methods are the distant cousins of conditional methods which also sometimes remove the call and the evaluation of the arguments.  But partial methods go even further.  When a partial method has no body then the partial method is not even emitted to metadata.

So far this might seem a little confusing.  C# now allows users to declare methods for which the calls, the evaluation of the arguments, and the method itself are not emitted.  Fortunately, the story doesn’t end there.  Partial methods allow users to define a body for the method so that the method, the calls, and the evaluation of the arguments are emitted.

partial class C
{
  static partial void M(int i); // defining declaration
  static partial void M(int i)  // implementing declaration
  {
  }
}

In the code above, we see that there is a difference between a defining declaration of a partial method and an implementing declaration of a partial method and the difference is whether or not the method has a body.  These definitions don’t have to be in the same partial class declaration.  There may only be one defining declaration and if a defining declaration exists then there may be an implementing declaration.

Why Partial Methods?

So how are these partial methods used?  The common scenario is to use them to do lightweight event handling.  For example a tool that generates code may wish to have hooks for users to customize what code is run.  For example, imagine that a tool generated a bunch of code for a class representing a customer.  It might look like this:

partial class Customer
{
  string name;

  public string Name
  {
    get
    {
      return name;
    }
    set
    {
      OnBeforeUpdateName();
      OnUpdateName();
      name = value;
      OnAfterUpdateName();
    }
  }

  partial void OnBeforeUpdateName();
  partial void OnAfterUpdateName();
  partial void OnUpdateName();
}

If the user doesn’t add any implementing definitions then this code is equivalent to:

partial class Customer
{
  string name;

  public string Name
  {
    get
    {
      return name;
    }
    set
    {
      name = value;
    }
  }

}

No extra metadata for things that are not used and no extra instructions for useless operations.  On the other hand if the user listened to the OnUpdateName “event” like this:

partial class Customer
{
  partial void OnUpdateName()
  {
    DoSomething();
  }
}

Then the original definition is equivalent to:

partial class Customer
{
  string name;

  public string Name
  {
    get
    {
      return name;
    }
    set
    {
      OnUpdateName();
      name = value;
    }
  }

  partial void OnUpdateName();
}

Comparing Partial Methods to the Alternatives

At this point, it is sensible to ask why not just use subclassing and virtual methods?  Of course, this would also work but it does have the drawback that the calls, the methods, and the evaluation of the arguments will still be emitted even if the virtual methods are not overridden.  So in a system like Linq to SQL that has thousands of little events it allows these events to be very lightweight so that the user only pays for those events that she uses.

A Few Fine Points

Consider the following program…

partial class C
{
  static void Main()
  {
    int i = 3;
    C.M(i = 5);
    Console.WriteLine(i);
  }
}

What does it write to the console?  3, 5, …?

Actually, it is impossible to tell from just this code.  If there is no implementing declaration then the program will display 3 because the i = 5 will never be evaluated, but if there is an implementing declaration then the program will display 5.  The same is true for conditional methods.  So if you want a side-effect to occur make sure you do not cause the side-effect to occur as an argument to a partial method.  Of course, the same trick can be used to hide expensive calculations.

partial class C
{
  static void Main()
  {
    C.M(VeryVeryExpensiveCalculation());
  }
}

If there is no implementing declaration then the very very expensive calculation will never be performed.

Now what about attributes, how does those work?

partial class D
{
  [W]
  [return:X]
  partial void M<[Y]T>([Z]int foo)
  {
  }

  [Z]
  [return:W]
  partial void M<[X]T>([Y]int foo);
}

What attributes are actually emitted on M?  W and Z are the attributes on M; X and W are the attributes on the return type; Y and X are the attributes on the type parameter; Z and Y are the attributes on the parameter.

Enjoy!

Comments (93)

  1. Luke says:

    Do you allow out parameters?

    Your specific example looks like Aspect Oriented Programming, except in a very limited fashion — might the C# team be moving in this direction?

  2. Aaron says:

    This sounds oddly like a c/c++ header file. with out the link errors.

  3. Pete says:

    Cool!

    My reactionary reaction – "partial method" is a confusing name for this feature. If I’ve understood, there’s always exactly one prototype and exactly zero or one definition bodies for this kind of method. That relationship is not one of "partialness" – partialness is a relationship allowing for *multiple* additiveness.

    If I were explaining what this feature was, I’d call them "optional" methods. How come you didn’t go for that?

    Pete.

  4. wesdyer says:

    Luke:

    No, no out parameters but ref parameters can do much of the same thing.  AOP has been and is still on the design team’s radar.

    Aaron:

    Indeed.  Except for the part of removing the calls and the evaluation of the arguments.

    Pete:

    I can definitely see what you are driving at and you make a very good case for "optional" methods.  The reason that they are partial is because they are usually used to "implement" methods in a partial class that are defined in a different class declaration.  So the name emphasizes the relationship to partial classes.  Originally we were calling them latent and actual methods and incidentally I still think of them that way.

  5. Derek says:

    Partial methods are somewhat interesting … I could see them being used for a logging framework that doesn’t require runtime configuration flexibility (in a performance sensitive area of code, for example).

    Because the log message construction is often expensive, this avoids the message construction overhead in cases where the given debug level is disabled without resorting to precompiler ugliness. In most cases I think the runtime flexibility would be more valuable, but it doesn’t hurt to have this option.

    It would also be a nice alternative to precompilation statements in platform specific areas of code … e.g. use a 32-bit native math library when compiling for 32-bit platforms, but fall back to a slower managed implementation that works on all platforms. This would allow you to branch the compilation in a build script, which seems cleaner.

    Beta 1 is nice, by the way, I especially appreciate the lightweight framework-only installation. I had been using the May CTP until beta 1 came along.

  6. wesdyer says:

    Looks like you see exactly how they might be useful.  I’m glad you are enjoying beta 1.

  7. Pete says:

    re. latent / actual keywords

    Yes, this is much more intuitive (if cumbserome), I realise that I did have the right understanding of what this feature really is.

    There is a relationship between the prototype part and the (optional) body part, but this is completely different to the one that exists between one partial class definition and another.

    My first thought reading the title of your post was "how do you decide which part of the method gets to run first!" – and I think that’s the initial understanding you’ll get from most developers if call this feature "partial methods". I do think this confuses a cool and otherwise easy-to-understand feature.

    Clearly we’d like to use the same keyword at the prototype and the body to simplify things, but the problem is that using one adjective implies that the two things are the same sort thing when they’re not…

    Pete.

  8. wesdyer says:

    Very good point.  I will bring it up immediately.

  9. Pete says:

    … interstingly, "optional" doesn’t suffer from this problem, as it doesn’t imply parity between the prototype and the body – you get the best of all worlds, the same keyword on both bits, which conveys the relationship between the two, and no confusion from overloading or messing up the existing "partial" keyword’s sense – as well as an intuitive keyword describing what the language feature does….

    Pete.

  10. Pete says:

    …but then again, while "optional" is good for the prototype part, it is terrible from a usability point of view for the mainline scenario.

    partial class Customer

    {

     // in what sense is this optional?

     optional void OnUpdateName()

     {

       DoSomething();

     }

    }

    Ideally, we’d just like to be able to write the method normally. Intellisense could prompt us that it is there to be written (as when typing "override "). Is there any deep reason why we need a special keyword at all on the implementation body?

    Thanks again,

    Pete.

  11. From what I’ve seen, this is a compile time feature.  It would be helpful if I could deliver a class library assembly to somebody which they could then customize by writing bodies to partial methods.  Is that possible?

  12. Anton Backer says:

    Why limit the partial method to one implementation? In the publisher/subscriber model of events, the order in which the handlers execute is explicitly unspecified (afaik) and I think it’s fairly intuitive to apply that model here, especially given the already established meaning of the "partial" modifier. Multiple implementations, unspecified execution order. The only reason against this that I can think of is the loss of clarity, but I think clarity was already lost back when partial classes were introduced.

  13. Stefan Wenig says:

    While I realize that this is a useful features in certain scenarios, I’m really unhappy that you implement this.

    So far, I’ve always had the impression that the designers of C# have been very careful about introducing new features. Like, there have been some arguments about whether the query projections are too specialized for a general purpose language, but then others wanted XML literals too and I’ve been quite comfortable with the decisions you’ve made there, and the reasons you offered.

    But now you implement a new language feature for a designer some other team is building, and this bothers me.

    First, because I’m not a big fan of designers. I’m quite worried they’ll soon enough be sending us down the same road that COM-based development went in its last years, with hundreds of designers and wizards that generated ATL and MCF code nobody ever wanted to read. The Ruby crowd will be laughing their asses off with a few lines of source where we’ll be stuck with designers and generated files and complicated build processes. (Compare that to COM/C++ vs. Java in the late 90s!) Wasn’t C# about code-based developer productivity in the first place (vs. VB’s designer-driven RAD road map)? You should be the last to care about the whims of the designer-based, enterprise-library-minded, software-factory-code-generator-happy folk. Resist!

    The second reason I’m unhappy is that there are more important features missing from C#. A lot of advanced C# developers want to walk down more dynamic paths without throwing the baby out with the bathwater and surrendering completely to dynlangs. There is still no generic ldtoken-like command for anything but types (typeof); attributes are still very limited (lambdas, generics, composition, order); AOP and DBC (Spec#) are far from easy to implement with C#… So while partial methods are not useless, they seem like the first sign of weak prioritization to me. Please don’t make this a habit!

  14. Tom Kirby-Green says:

    Awesome to have you back in the blog sphere Wez. Partial methods look so cool. I was wondering when you folks are planning on updating the C# 3 language spec doc?

  15. Tom Kirby-Green says:

    Actually to return to something you spoke about before. With C# 3 what percentage of your "language complexity" budget do feel you have left? Personally I’d like to see language bindings for concurrency over things like AOP. I really do feel strongly that C# should not descend into the murky waters of corner cases and language laywers that is commonly found in the C++ domain. Or is Ander’s way ahead of us again (probably) and already working C#’s replacement :-)

  16. Pete says:

    Yep, I’ve mulled it over and I would find the following syntax a lot more helpful. Any reason why it couldn’t work Wes? (Do we really need a special keyword on the implementation part?)

    class C

    {

       optional void DoIt(int i);

       // …

       void DoIt(int i)  // optional implementation

       }

       {

    }

    This would make the feature clear to those who need to understand it, and transparent to those who just need to use it (writing the implementation).

    Pete.

  17. Pete says:

    The only prob I can see is that you might argue that it’s not obvious that you *can* write implementation…. that you need a keyword as in the case of "override". I don’t think this is how many (most) day-to-day developers work tho. Most don’t think about how their event handler is being hooked up (whether it’s auto-wired or overriding a virtual) – they just write the method.

    This could be solved by appropriate tooling – intellisense could show un-implemented optional methods in grey instead of black or something.

    Pete.

  18. madstorgersen says:

    Lots of questions on why the implementation also needs the keyword: this is to catch errors. If you make a small mistake which changes the signature of the implementation you want the compiler to tell you that. If you didn’t have the keyword, then having an unimplemented partial method and a slightly different normal method would be perfectly legal, and you wouldn’t catch it.

    Mads Torgersen, C# language PM, Microsoft

  19. wesdyer says:

    David:

    Good question.  No it is not possible to provide partial method bodies that way because it is only a compile time feature.

    Anton:

    Interesting idea.  What order would the subscribers be called in?

    Stefan:

    YOu have some very good points.  I still don’t think that C# adds features at a whim.  The feature is quite useful for code generation frameworks in general.

    As for the features that you want to have addressed, they are being talked about for Orcas+1.  Having done the implementation for partial methods and having looked at implementing some of the other features that you mention, just remember that there is *at least* an order of magnitude difference in the cost to implement those features.

    Tom:

    The spec isn’t updated?  Which one are you referring to?  Could you give me a link?

    Honestly, there is not a lot left of the complexity budget in my opinion.  I think new features have to dovetail very nicely within the existing mental framework or they will be too much.

    Pete:

    I really like the idea of graying out call sites for unimplemented partial methods.

  20. Pete says:

    Mads,

    Thanks, of course – I knew there had to be a reason – I was stuck on thinking about versioning issues (e.g. what if you add a partial prototype with the same signature as an existing normal method) – which seem to not be a problem. Didn’t think about the obvious.

    Thanks,

    Pete.

  21. Pete says:

    class C

    {

      optional void DoIt(int i);

      // …

      void DoIt(int i) : optional void DoIt(int i)

      }

      {

    }

  22. wesdyer says:

    Pete:

    Do you really want to repeat the method signature?

    optional void DoIt<T,U>(Dictionary<T,List<Pair<T,bool>>> d, Set<Tuple<double, bool>> s);

  23. Daniel Plaisted says:

    No one has answered the question about what attributes are emitted when theydiffer between the definition and implementation.  My first instinct is that it is a trick question.  It seems like this should cause a compile error.

    Maybe there are cases where you need to apply an attribute to a partial method but the code generator won’t do it for you when writing the defining declaration.  If that is the case, maybe the compiler combines the attributes from both declarations, or just doesn’t allow attributes on the defining declaration.

    There are probably other ways of handling it, but I think they would be even more complicated and more likely to confuse people.

  24. Pete says:

    Just grasping at straws…! Pete

  25. Stefan Wenig says:

    Wes,

    I’d agree with you about the cost of implementing AOP or DBC, but ldtoken or better Attribute support would actually be _relatively_ easy to implement.

    For ldtoken, consider the following workaround which has been posted on various blogs and MSFT connect:

    MethodInfo GetMethod<T,A0,A1,…R> (Expression<Func<T,A0,A1,…R>> func)

    {

     // pick methodinfo from expression tree

    }

    MethodInfo m = GetMethod ((StreamWriter w, string s) => t.Write (s));

    an easier syntax to speficy this would be:

    MethodInfo m = methodof (StreamWriter, Write, string);

    in c++, you could define a macro to make that transformation:

    #define methodof(T,meth,A0)

     GetMethod ((T t, A0 a0) => t.Write (a0));

    now if a preprocessor can do that, how hard could it be to have it in c#?

    of course, a nicer syntax would be

    MethodInfo m = methodof (StreamWriter.Write(string));

    since you operate on the AST, I think it makes little difference effort-wise. There will be stuff to consider more carefully of course, but that’s true for partial methods just as well, and that’s what got me started here.

    As for the attribute syntax, it’d be almost as easy to create a preprocessor that does a transformation to a workaround that is possible in c# today, although this preprocessor would have to know about the c# AST (classes and members basically, not expressions, statements or any semantics)

    I’ve already posted this with eric lippert (and I was just as OT as I’m right now…):

    http://blogs.msdn.com/ericlippert/archive/2007/05/15/should-we-produce-warnings-for-unused-uninitialzied-internal-fields.aspx#2669506

    It’s just a workaround, granted, but anything better would probably turn the CLR upside down, including metadata format and reflection APIs. (But hey, if you’d touch this, you could add support for generics with variable-length type argument lists, like C++ 0x too ;-))

    (BTW, the attribute-workaround would make the ldtoken feature work in attributes to, which is where my team needs them most desperately!)

    It’s encouraging though that you’re considering some of that for post-orcas. You’d make a lot of people happy!

    Thanks for taking this serious!

    Stefan

  26. Couple of interesting posts; Partial Methods I spent quite some time thinking about the difference here…

  27. Let us corrupt C# for code generators: The horror story of partial methods

  28. Aaron says:

    How can making simple code like:

    int i = 3;

    C.M(i = 5);

    Console.WriteLine(i);

    Impossible to predict without knowing the entire class definition, a GOOD thing?

    May I suggest adding another keyword for calling partial methods?

    int i = 3;

    imisstheoldcsharpbeforetheygotsickwithfeaturecreep C.M(i = 5);

    Console.WriteLine(i);

  29. Lazy Coder says:

    1. Test Driven beta supports Orcas Beta 1 integration. I have been holding off converting one of our…

  30. rbirkby says:

    Partial methods feel like premature optimization.

  31. Blog says:

    How to pollute C#

  32. wesdyer says:

    Daniel:

    You are right.  The attributes are combined from both definitions.

    Pete:

    Aren’t we all grasping at straws…;)

    Stefan:

    I agree that ldtoken looks easier to design and implement and we looked at doing it but decided against it for Orcas.  One problem that you touched on is how do we pick some method out of a method group with ldtoken.

    var f = infoof(C.F);  // what if there are multiple Fs

    We would need a way to specify method signatures which means extending the syntax or we would need variable arg infoof operator but that is a little strange.  This isn’t as simple as it seems nor does it have a very small surface area.  It is still on the table but we were not satisfied with what we have.

    I would also love variable length type argument lists.

    Ayende:

    Could you explain the horror?

    Aaron:

    That may be true but it could be worse…consider conditional methods.  You already don’t know if the call and the evaluation of the arguments occurs until you know if C.M is a conditional method *and* whether or not the definitions it depends upon are in fact defined.

    I really think the IDE should do something here to help people out like gray out conditional methods and partial methods (at the call site and the declaration) that are removed.

    RBirkby:

    It does feel that way doesn’t it.  You might ask why not have the JIT optimize this somehow but that won’t work because the metadata bloat is still there and it would require new CLR mechanics to accomplish the same semantics.  You might ask why not have the C# compiler just optimize the situation but that wouldn’t be an optimization because it would change semantics both at the call site and in terms of reflection.

    Like I said before much of the same thing can be accomplished by subclassing and virtual methods in combination with a pattern that abstracts creation like the factory pattern.  The big difference is that here the metadata is much less because it removes the methods and the call sites are modified.

    To All:

    Btw, I should also mention that it is illegal to call a removed conditional method or partial method in an expression tree.  The reason should be somewhat obvious…how do you represent it in the tree if it is gone?

  33. wesdyer says:

    I should also mention that by far the common case *should* be for users to *not* write calls to partial methods.  They should typically only provide implementions for them.  The definitions and the call sites should be typically generated by code generators.

  34. Aaron says:

    Yikes, I had forgotten about Conditional attributes.  Actually… that makes me wonder now, why do we need this if we already have the new partial methods if we already have the Conditional attribute?

    Anyways, you guys are of course free to do what you’d like with C#, its yours of course.  This feature is not the end of the world or anything.  It just irks me, and people like me I think, when features are added that just increase the complexity of the language without adding much real benefit to the coders out there.  Especially when the feature is added for the benefit of the automated designer instead of the user 😉  

    I just wonder if instead of making C# 3 (or is it 3.5?) you all should have created a new language to put all those new features in rather than adding them to C#, maybe you could have kept C omega around for instance.  Remember that one of the reasons that people were very happy to move from C++ to Java and C# was that they were both much simpler languages.  That is not as much the case as it used to be.  

    I am looking forward to a bunch of features in C# 3, but I am a pretty experienced developer and am proficient in C# and C++.  I can handle this stuff and understand it and enjoy it.  I dont know about most programmers.  It seems to me this stuff is going to do more harm than good in the long run.

  35. Sadek Drobi says:

    Nice to hear back from you Wes,

    Well actually myself i dont like code generators, so i would agree with some of the points of Stefan.

    I ve been waiting for the beta expecting to c anonymous classes, but they are not there :(

    I really beleive that they add a lot together with extension methods… Anyway, waiting for the release!

  36. No, not partial classes. Partial methods. As Wes talks about in his latest post on language enhancements

  37. Dan says:

    I don’t like the fact that it’s impossible to determine if your function call, and possible side-effects, will be executed or not.

    Two suggestions:

    1) Give the partial/optional method special visibility, so that only partial classes that define the partial method can call it, either the "latent" or "actual" part. That way you won’t be able to write in code that won’t execute unless you specifically defined it to be optional in the same source file.

    Or 2) Make it necessary to add a keyword to the method calls "C.partial M(5);", this way you will also be aware of that the method call might never happen.

    I think I prefer #1 over #2, but it might restrict its usage a bit too much (for instance the logging example Derek mentioned).

    Of course you could combine both, forcing you to use the partial keyword if you have not defined the partial method in this source file.

    As for keyword for the "actual" method, how about "override partial" as a combined keyword?

  38. Stefan Wenig says:

    Wes,

    I’m not going to bother you here forever over off-topic stuff like infoof, but I think by showing how it can almost be implemented using the c preprocessor, I’ve set the bar for justified rejection a bit higher than just claiming that it’s a bit harder (although it’s not beyond me to imagine it might be).

    While it would be interesting to follow up on this (or the attribute proposal, for that matter), the elephant in the kitchen is the fact that there is no process for discussing c# enhancements within the community before everything is written in stone.

    The way you’re designing C# seems to work better in some aspects than the java community process, so I’m not sure how far you should really go. But getting feedback and discussing suggestions early is definately overdue. You can do that easily without losing control. There’d be a lot of noise to filter out, but that’s hardly an excuse for not doing anything at all. Hear us while it makes a difference, there’s going to be usefull stuff in it for you! Plus, language competition is increasing lately. You don’t want to lose the language geeks, do you?

    What do you think?

    Stefan

    PS: Is AOP really an effort problem, or is it true that anders just hates it with a vengeance?

  39. Brian says:

    I agree with Stefan Wenig.

    There are so many other features that need to be implemented. This one has very little actual value, but increases the complexity of of the language and manageability of code substantially.

    Judging from the usages cases I have read here, I do not think I will have any practical use for it. And I hope that I do not see it when I review other people’s code.

    The case for designers is very marginal. While I am not very fond of designers and prefer to write my own code, I recognize that many people use them. However, I am outraged that you would pollute the language for all to justify designers of all things.

    There are precisely two features that I want, and I have been asking for them since before Whidbey was in beta.

    1) Generic variance.

    2) Operator constants.

    Until these features are introduced, I must resort to editing some of my code directly in IL to overcome these limitations.

  40. Stefan Wenig says:

    Brian,

    generic variance (though it would have to be optional) would be really great, agreed. I guess we’ve all had our problems with that stuff, including copying whole lists to their base class type.

    When implemented like arrays, it would also mitigate the problem that generic classes do not have a common base type – they would all derive from GenericType<object>! (well, except value types, again)

    what are operator constants?

    Stefan

  41. My code generation scenario is slightly different. I should like to produce a partial class from a UML style class diagram. Partial classes are the right thing, as code level information is then added in an other source file. However, I should like the generator to produce the declaration of methods, so that the rest of the code can use these methods. The compilers job is then to *ensure* that these method stubs are actually implemented in some other partial class, that is the implementation is required by the compiler, the calls should not be removed.

    Btw, this seems like reverse aspect oriented programming, you write all the aspects inline, but remove them at compile time if you do not need them :-)

  42. Samuel Jack says:

    What about requiring partial methods to be protected or private? This would limit visibility to places where callers are most likely to understand the intention of the method.

  43. Tom Kirby-Green says:

    I know this is going off topic – but this caused me to run into a mental brick wall today. With the incresing use of anonymous blocks of code in form of anonymous delegates or lambdas how do you unit test? How can you build a framwork reach in and verify an essentially unnamed chunk of logic. Do we have to start referring to those lovely compiler generated mangled names? How are folks unit testing their anonymous code blocks today? Help! :-)

  44. wesdyer says:

    To All:

    Partial methods *must* be private.

    Aaron:

    Partial methods differ from conditional methods in that the method is removed as well as the call sites.

    Sadek:

    What are anonymous classes?  Do you mean anonymous types?

    Dan:

    Good ideas.  I will bring it up.

    Stefan:

    That would be fantastic for a prototype but not for a finished language feature.  I am not sure that the syntax is quite right yet which is what I was alluding to before.

    There are some ways to discuss language enhancements but I will bring up the issue with Mads.  Until then try making suggestions, I know that the suggestions *are* evaluated for possible enhancements.

    The general consensus is that we like AOP, but we are not sure if it is ready for primetime yet.  It is continually being evaluated for inclusion.

    Brian:

    Thanks for the feedback.  We were talking about covariant generics again just the other day in the design meeting.  What do mean by operator constants?

    Kasper:

    Good to hear from you!  That scenario makes a lot of sense.  I wanted exactly that when I was writing some compiler generation tools.  You are right, it is kind of reverse AOP.

    Samuel:

    Partial methods *must* be private.  That is a very important point.

    Tom:

    Do you mean how are people testing the actual anonymous code blocks or how are people testing functions which take delegates?

  45. Stefan Wenig says:

    You are of course right, without even mentioning the problem of out/ref parameters this is not perfect. It was just ment to be an indicator of how hard it could be. But I’m beating my point to death…

    As for the discussion process, I know that there are ways, but they basically all suck. I can make suggestions at connect, but that’s no place to discuss stuff. I’m not talking about voting either, things like AOP are far too complicated to be discussed in this matter. I’d like to see a discussion between language geeks inside and outside of MSFT, voices from framework developers (the nhibernate/castle kind) and application developers, etc. This is all happening in the blogosphere – except that it’s fragmented and the C# team is not really participating.

    As for AOP: Have research build a prototype while you absorb the good bits from spec# into C# – this has worked quite well with Comega and LINQ, I guess everyone would like to see this success story repeat!

    You’re doing good work, but everyone can use some help and some outside perspective from time to time. And there’s more to that than posting suggestions. If you find a way to make this fly, I’m gonna drown your blog in praise! 😉

  46. Stefan Wenig says:

    Tom,

    how do you unit test private methods? You could invoke them using Reflection, but the truth is that the need to do this is rather rare even in TDD. They are usually tested indirectly via the public methods that use them, and it’s going to be the same with anonymous methods.

    In the rare cases where you absolutely have to test them, you could still pass mock objects to the outer (named) methods and have the mock accept the anonymous one. Like using Reflection, this is not too much fun, so it should be the exception.

    Stefan

  47. wesdyer says:

    Stefan:

    We want that kind of experience.  The team regularly has open discussions with MVPs about the language.  We also have online chats that are open invite as far as I am aware.  If we see stuff out in blogs then we try to comment and participate.  So I guess one big question is where in the blogosphere is this happening that we are not participating?

  48. Stefan Wenig says:

    You know, I see the odd comment from an MS guy here and there, but it doesn’t add up to give me the feeling that there’s an active participation. Probably depends on the blogs one has subscribed. You miss some, I miss some, in the end you just hope to stumble across stuff. It’s very unstructured too, I’m sure you can do much better that this if you actually do some kind of coordinated effort. A forum or a wiki where all kinds of language features can be discussed in detail would be a so much better place to do this. This has worked before in other contexts, so why not try it?

    I sometimes post to MS blogs off-topic, but this is the first time that this resulted in a dialoge like this one. MVPs are a somewhat closed group too, and chats are easily missed. I’m afraid I can’t give you any detailed info on what’s missing, just my feeling that the status quo is dissatisfactory and I think you’d easily figure out a better way I you agreed to that notion.

    From what I gather from other people’s blogs, I think there are quite a few people who feel the same way. Like I said, competition in the language area is rising, so what was good enough some years ago might not do it today.

  49. mattwar says:

    Yes, yes, yes. This is the inverse of AOP.  With AOP you manually write a bunch of code and rules and then run a tool that programmatically identifies hook points in your code based on your rules and injects new code at those hook points. With partial methods you run a tool to programmatically generate a bunch of code with pre-defined hook points and then later manually write code to get called at those hook points.

  50. brian says:

    wes,

    Sorry about the late response.

    I am thrilled to hear that the team is reconsidering covariant generics. I think that feature work will need to be done first in the CLR though. Please keep us updated on any developments.

    Just for reference, Microsoft Research produced a great document discussing covariant generic issues and solutions:

    http://research.microsoft.com/research/pubs/view.aspx?type=inproceedings&id=1215

    By "operator constraints", I mean a way of constraining a generic T to an interface that defines operator overloads. In a generic type, you need to prove to the compiler that a type T does in fact contain the desired methods before it be called. This is done like:

    where T : IFoo

    Operator overloads, due to their implementation details (which I should not need to care about), must be static. An (C#) interface can not contain static methods. Therefore, I can not prove to the compiler that my type T actually does override specific operators.

    Consider the following type (hopefully the formating goes through):

    struct Foo<T>

    {

     public Foo(T bar)

     {

       this.bar = bar;

     }

     public static Foo<T> operator+ (Foo<T> f1, Foo<T> f2)

     {

       // Error CS0019: Operator ‘+’ cannot be

       // applied to operands of type ‘T’ and ‘T’

       return new Foo<T>(f1.Bar + f2.Bar);

     }

     public T Bar

     {

       get

       {

         return bar;

       }

     }

     private readonly T bar;

    }

    As noted, this will error because T may not contain an operator+ method. Ideally I would create an interface with the desired method and constrain the T to it. However, due to their static nature, that is not possible. Thus, I must give up overloaded operators or use ugly alternatives, neither of which are very desirable.

  51. wesdyer says:

    Brian:

    Ah, operator *constraints*…yes I know what those are.  We talk about constraints often too.

    And we are in regular contact with the MSR folks.

  52. Tom Kirby-Green says:

    What I meant was how are people testing actual anonymous code blocks. The ‘anonymous logic’ coding style seems somewhat TDD hostile. Don’t get me wrong I love anonymous delegates and their kin – but am concerned about the testing issue also.

  53. Sadek Drobi says:

    no i mean anonymous classes…

    so that i can define extension methods for an interface, then i implement anonymous classes that implement the interface. this way they inherit the extension methods.

  54. Stefan Wenig says:

    Tim, that’s what I understood, but let me try to be a bit more specific. How do you test this lambda:

    public void foo () {

     bar (a => 2*a);

     …

    }

    The answer is of course: By testing foo. From a testability point of view, it’s in fact no different from this:

    public void foo() {

     … = bar (…);

    }

    private int bar (int a) {

     return a * 2;

    }

    Since bar is private, you can’t easily test it directly, and experience shows that it’s usually not necessary. Now if you really had to do it, you’d have to do something ugly like this:

    MethodInfo m = type.GetMethod ("bar", BindingFlags.NonPublic | BindingFlags.Instance, new Type[] { typeof (int) });

    Assert.Equals (4, m.Invoke (obj, new object[] {2});

    You think this is TDD-friendly? No, it just works because you dont have to do it often.

    And there is an ugly workaround for testing anonymous delegates too. You need to pass the object that accepts the delegate via an interface and mock it:

    public void foo (IXY xy) {

     xy.bar (a => a * 2);

    }

    class XYMock: IXY {

     public void bar (Func<int,int> f) {

       Assert.Equals (4, f(2));

       Assert.Equals (0, f(0));

     }

    }

    [Test] FooBar() {

     IXY mock = new XYMock();

     obj.foo (mock);

    }

    So just like directly testing private methods, it’s possible but ugly, and fortunately you don’t need to do it a lot.

    Btw, you could also make this more flexible by passing the actual test to the mock via a delegate, if that does not exceed your mental delegate stack depth 😉

    [Test] FooBar() {

     obj.foo (new XYMock (2, r => Assert.Equals (4, r)));

     obj.foo (new XYMock (0, r => Assert.Equals (4, 0)));

    }

  55. Gunter says:

    I know this is off-topic now, but i wanted to say something about (against) operator constraints :)

    The way constraints in C# work right now is that they enable you to program against "behaviors" of generic parameters. These behaviors are expressed by interfaces, that’s exactly what interfaces are for.

    If you go down the road of "operator constraints" you will end at constraints which just check if a certain method signature is existing in a generic parameter. But two different classes implementing a method with the same signature don’t necessarily have the same semantics.

    You have that problem too even if you stay only with operator constraints. A operator+ means something entirely different for an int and a string.

    The right thing to solve the problem is to introduce an interface describing the behavior you want to use: All basic number types (byte, int16, int32, int64, float, double) should be derived from an generic interface IBasicArithmetic<T> which defines the four basic operators Add, Subtract, Multiply and Divide.

    This still means you have to use t1.Add(t2) instead if t1 + t2, but i think one can live with that (and probably an operator+ could be implemented inside the generic class using the IBasicArithmetic interface to reenable that).

    Gunter

  56. Brian says:

    Gunter,

    I basically agree and have argued for a similar system in the past. The lack of an IBasicArithmetic<T> interface makes it impossible to know what can be added and whatnot. I do not really care about the actual implementation. In the end, I just want to be enable the usage scenario.

  57. Gunter says:

    This IBasicArithmetic<T> interface would be really helpful in some generic scenarios and i think it could included in Orcas rather easily. Surely much easier than operator constraints (i never thought operators should be used for more than arithmetic types and strings anyway).

    Is this being considered (I didn’t have a look at the beta yet)? Or where is the best place to vote for? :)

    Gunter

  58. Brian says:

    Gunter,

    I think it should be a little more fine-grain control. For example, it makes sense to add (and maybe even subtract) two strings, but what does it mean to multiple or divide two strings? There are many other examples where some operations make sense, while others do not. Thus, I propose the following:

    public interface IAddable<T> {…}

    public interface ISubtractable<T> {…}

    public interface IMultiplyable<T> {…}

    public interface IDivisible<T> {…}

    public interface IBasicArithmetic<T> : IAddable<T>, ISubtractable<T>, IMultiplyable<T>, IDivisible<T> {}

  59. wesdyer says:

    Gunter & Brian:

    Great ideas.  Post them as suggestions to the team.  The suggestions are triaged.

    Btw, you said something about signatures not ensuring semantics.  This is true but interfaces do ensure semantics either.

    You also might want to look at type classes in Haskell.  They are very similar to what you want.

    Sadek:

    That won’t be in Orcas.  Hopefully next go around something can be done.

  60. Gunter says:

    Brian,

    Good idea, signed by me :)

  61. Brian says:

    There are already a number of similar suggestions on Connect. All are slightly different, but generally amount to the same feature request. See IDs 91040, 92816, and 90956, and probably others, for details.

    Do you suggest another variation be submitted?

  62. Thomas Eyde says:

    My turn-off to this is that partial methods looks like a method, walks like a method, but doesn’t quack.

    If I can’t decide what to return, or the scope of visibility, it isn’t a method at all. Not to me.

    And it’s unfortunate that parameters aren’t always evaluated. Now I get a new, powerful tool to create more subtle bugs.

  63. Over the last few weeks I’ve been writing a series of blog posts that cover LINQ to SQL. LINQ to SQL

  64. Over the last few weeks I’ve been writing a series of blog posts that cover LINQ to SQL. LINQ to SQL

  65. ASP.NET says:

    Over the last few weeks I’ve been writing a series of blog posts that cover LINQ to SQL. LINQ to SQL

  66. Easy Company says:

    在 .net framework 3.5 中增加了一个新的功能叫做分部方法(partial method,因在.net framework 2.0中partial class在msdn中译做分部类型,所以此处暂称为分部方法)。分部方法是一些方法,它使轻量级的事件处理成为可行。它被包含在VS 2008 Beta2中的 VB 和 C# 中,本文将以C#来说明…

  67. I have spoken to quite a few customers about LINQ &amp; LINQ to SQL over the last few months. Oddly enough,

  68. I have spoken to quite a few customers about LINQ &amp; LINQ to SQL over the last few months. Oddly enough

  69. La Beta 2 de Visual Studio 2008 est arrivée très récemment et avec elle, on retrouve pas mal de petites

  70. Anders Liu says:

    在看C#语言的What’s New时,突然发现新特性列表的最后,多出了一个“Partial Method Definitions ”,但并不像其他新特性一样有超链接链接到其说明。上网搜索了一下,关于分部类型的信息非常少。尤其是中文信息,只有CSDN的 周融 在其《C# 3.5 语言在 Visual Studio Orcas Beta 1 上的新增功能(二) 》一文的最后提到了这个分部方法,但没有进一步说明。英文技术文章中,倒是有两篇不错的:http://blogs.msdn.com/wesdyer/archive/2007/05/23/in-case-you-haven-t-heard.aspx

  71. Joe Rattz says:

    Hey, since no one likes the keyword ‘partial’, how about ‘ghost’?  If an implementation doesn’t exist all hints of the method just vanish.

  72. Darth Bundy says:

    Firstly, I must confess that up until now I have not really known about partial methods. Whenever I encountered

  73. BenkoBlog says:

    A good question on Partial Methods Yesterday in Kansas City I got a question during the LINQ session

  74. Can find simple examples for VB.net partial methods. helpfull for newbies

  75. Last time I mentioned that one of the subtleties of programming language design is weighing the benefit

  76. Drew Noakes says:

    Would the compiler raise a low-priority warning if you attempted to define the latent and actual methods in the same file?  It seems to me that a warning here might help people understand the feature a little better.

  77. We all know the great new feature in .NET 2.0 framework &quot;Partial classes&quot;. You can write code

  78. Paul Sanders says:

    Very helpful writeup; well written, concise and easy to follow. Thanks very much.

  79. chris lively says:

    If I catch anyone working for me using partial methods I will fire them on the spot.

    How much more difficult do you guys really think programming should be?  

    This type of garbage will make debugging that much more difficult without adding any real value to the language.  Why not just through this in the VB.net language and leave C# alone.

  80. John Chapman says:

    Thanks for spending the time to explain this new feature in .NET 3.5.  But I’m really concerned regarding the usages for such a feature.  It seems like we could use other mechanisms to accomplish the same thing, such as the event framework we already have.  This just seems like a really dangerous tool when a developer not realizing the implications gets a hold of it.

    For more detailed comments see my blog posting:

    http://jaychapman.blogspot.com/2007/10/partial-methods-what.html

  81. Bobby says:

    I know I am a Johnny Come Lately on this, but what if I add an implementation of OnUpdateName as an Extension will the compiler pick that up?

  82. Wesley says:

    @chris lively: If I had a boss reacting like that I would quit my job by myself.

    And your last sentence "Why not just through this in the VB.net language and leave C# alone" proves that you don’t have a clue what .NET framework is. Stay on your graphical stuff and leave the real development for the experts.

  83. Navaneeth says:

    Hi,

    Thanks. Can you tell then what will be the difference for this from delegates ?

  84. Partielle Klassen gibt es seit zwei Jahren, also dem Release von .NET 2.0 und C# 2.0. Mit dem neuesten Release wurden nun auch partielle Methoden eingeführt, die das Konzept konsequent weiterführen. Was sind partielle Methoden? Sie folgen genau dem ..

  85. Riaz Afridi says:

    Partial methods are only usefull for desingers not for developers?

    Developer may not use partical method, b/c it does not make sense, if I am not going to provide an implementation of a method why I would define the prototype and add a call to this method.

  86. Rick O'Shay says:

    This is relatively clean but at some point they need to stop adding syntax sugar in the name of economic code or meta data. CPU cycles and bytes are cheaper by the day. Let’s profile code, then optimize if and only if there is a bottleneck in the actual running of the application.

    That you have to return void is obviously an internal implementation issue that is foisted on users of the language. When a language starts to break orthogonality, bad things happen. Can methods return values in C#? The correct answer, now, is "it depends".

  87. Chetan says:

    Please remove link above. It is broken. Sorry.