Looking for other C# programmers thoughts on partial methods

J

JDeats

So I have a class that spans over two partial classes in code, here's
an example (do not read much into this, the code is of no practical
use, this is just a simple example of where my confusion occurs).

// Inside SharedClassExample1.cs
public partial class SharedClassExample
{

public List<string> BooksOnShelf { get; set; }
public List<string> BooksOnDesk { get; set; }

// constructor
public SharedClassExample()
{
BooksOnShelf = new List<string>();
BooksOnDesk = new List<string>();
}

public void SortBooksOnShelf()
{
BooksOnShelf.Sort();
}

// why isn't this possible?
partial void RemoveBooksFromShelfAndDesk(string bookTitle)
{
BooksOnShef.Remove(bookTitle);
}
}

// inside SharedClassExample2.cs
public partial class SharedClassExample
{
public void SortBooksOnDesk()
{
BooksOnDesk.Sort();
}

// why isn't this possible?
partial void RemoveBooksFromShelfAndDesk(string bookTitle)
{
BooksOnDesk.Remove(bookTitle);
}
}


The above example generates a compile time error, after some research
on-line it appears partial methods do not work as I original
understood. Instead a "partial method" is simply defined in one file
(In context, "file" means one of the two files in which this class
lives, in two parts) and the implementation is provided in the other
file.

Some my question is this: If the implementation of the partial method
can not span across files, then what is the point? For example, in C#
2.0 with partial classes I could make a call SortBooksOnDesk from
inside SharedClassExample1.cs so why do I need this new mechanism of
seperating the implementation from the declaration?
 
J

Jeroen Mostert

JDeats said:
Some my question is this: If the implementation of the partial method
can not span across files, then what is the point?

The point is to allow code generators to generate code that can still be
extended by clients, without having to modify the generated code:

partial class Generated {
private void DoStuff() {
// Generated code here.
AfterDoStuff();
}

partial private void AfterDoStuff();
}

The client can now write up the other half of the class, implementing
AfterDoStuff(). If they don't, then there is no method and the call is
simply eliminated.

This could have been implemented with delegates or even events as well, but
if you have a lot of hooks this way (such as the ones provided by
LINQ-generated DataContext classes) this gets pretty clusmy and inefficient.
Enter partial methods as a simple, lightweight extension mechanism.

Basically, code generation is all that partial methods (and partial classes)
are intended to support.
For example, in C# 2.0 with partial classes I could make a call
SortBooksOnDesk from inside SharedClassExample1.cs so why do I need this
new mechanism of seperating the implementation from the declaration?
*You* don't. In fact, unless you're writing a code generator, there's no
reason to bother with "partial" at all. It only makes things harder to find.
If your class is so big that "partial" starts to look nice, it's time to
rewrite the class. Either that or paper over the hard bits with code
regions. That's still better than splitting up the class over multiple files.
 
I

Ignacio Machin ( .NET/ C# MVP )

So I have a class that spans over two partial classes in code, here's
an example (do not read much into this, the code is of no practical
use, this is just a simple example of where my confusion occurs).

// Inside SharedClassExample1.cs
public partial class SharedClassExample
{

public List<string> BooksOnShelf { get; set; }
public List<string> BooksOnDesk { get; set; }

// constructor
public SharedClassExample()
{
BooksOnShelf = new List<string>();
BooksOnDesk = new List<string>();
}

public void SortBooksOnShelf()
{
BooksOnShelf.Sort();
}

// why isn't this possible?
partial void RemoveBooksFromShelfAndDesk(string bookTitle)
{
BooksOnShef.Remove(bookTitle);
}

}

// inside SharedClassExample2.cs
public partial class SharedClassExample
{
public void SortBooksOnDesk()
{
BooksOnDesk.Sort();
}

// why isn't this possible?
partial void RemoveBooksFromShelfAndDesk(string bookTitle)
{
BooksOnDesk.Remove(bookTitle);
}

}

The above example generates a compile time error, after some research
on-line it appears partial methods do not work as I original
understood. Instead a "partial method" is simply defined in one file
(In context, "file" means one of the two files in which this class
lives, in two parts) and the implementation is provided in the other
file.

Some my question is this: If the implementation of the partial method
can not span across files, then what is the point? For example, in C#
2.0 with partial classes I could make a call SortBooksOnDesk from
inside SharedClassExample1.cs so why do I need this new mechanism of
seperating the implementation from the declaration?

IT's different than partial classes, in partial classes you are
effectively dividing an entity (in this case a class) among more than
one file.
partial methods are intended to be like more like a "if exist use it
if not ignore the call" kind of approach.
IIRC the iroginal intention was for the code generations framework
(like LINQ to SQL) where you can generate methods that call other
methods that might be implemented by the user, if those method exist
then the call is generated, if not the call is not generate hence no
performance overhead occur in the compiled code
 
J

JDeats

IT's different than partial classes, in partial classes you are
effectively dividing an entity (in this case a class) among more than
one file.
partial methods are intended to be like more like a "if exist use it
if not ignore the call" kind of approach.
IIRC the iroginal intention was for the code generations framework
(like LINQ to SQL) where you can generate methods that call other
methods that might be implemented by the user, if those method exist
then the call is generated, if not the call is not generate hence no
performance overhead occur in the compiled code

Thanks! You have both helped clear this up. Based on my new
understanding I think the term "partial class" is a misnomer, but
other than that I'm perfectly fine with them :)
 
J

JDeats

Correction: I think the term "partial method" is a misnomer. Wish the
team would have used a different term to describe this functionality.
 
J

Jeroen Mostert

JDeats said:
Correction: I think the term "partial method" is a misnomer. Wish the
team would have used a different term to describe this functionality.
What, introduce a *new keyword*? That's a mortal sin among language
designers if you've got an existing one you can co-opt. Admittedly, C++ took
this a little too far... :)
 
I

Ignacio Machin ( .NET/ C# MVP )

Correction: I think the term "partial method" is a misnomer. Wish the
team would have used a different term to describe this functionality.

well, they could have choose a better one, that's for sure :)
 
A

.\\\\axxx

JDeats wrote:
rewrite the class. Either that or paper over the hard bits with code
regions. That's still better than splitting up the class over multiple files.
Except where different areas of the code might need to be worked on by
different developers - in which case it can be quite useful.
 
J

Jeroen Mostert

..\\axxx said:
Except where different areas of the code might need to be worked on by
different developers - in which case it can be quite useful.

Two thoughts:

1. Source control with merge semantics. It's what's for dinner.
2. If you can meaningfully split up a class so that two developers can work
on it independently, then it's two classes and glue, or even just two
classes. Refactoring time.

To put it clearer: I don't doubt that you *can* use "partial" to split up a
class to achieve something useful. I'm just saying that (in my rather
quickly formed opinion) you shouldn't, as there are clearly better
alternatives to achieve the same thing. The one clear exception is what the
thing was designed for: combining (re)generated code with manually written code.
 
J

JDeats

Two thoughts:

1. Source control with merge semantics. It's what's for dinner.
2. If you can meaningfully split up a class so that two developers can work
on it independently, then it's two classes and glue, or even just two
classes. Refactoring time.

To put it clearer: I don't doubt that you *can* use "partial" to split up a
class to achieve something useful. I'm just saying that (in my rather
quickly formed opinion) you shouldn't, as there are clearly better
alternatives to achieve the same thing. The one clear exception is what the
thing was designed for: combining (re)generated code with manually written code.

It seems these additions to the language were driven by the Visual
Studio,NET team to aid code generation. There are quite a few third-
party tools on the market that perform code generation that could make
use of these techniques, but they aren't for everyday use in my case.
 
B

Brian Gideon

Two thoughts:

1. Source control with merge semantics. It's what's for dinner.
2. If you can meaningfully split up a class so that two developers can work
on it independently, then it's two classes and glue, or even just two
classes. Refactoring time.

To put it clearer: I don't doubt that you *can* use "partial" to split upa
class to achieve something useful. I'm just saying that (in my rather
quickly formed opinion) you shouldn't, as there are clearly better
alternatives to achieve the same thing. The one clear exception is what the
thing was designed for: combining (re)generated code with manually written code.

I think a good use, other than code generators, is to locate larger
nested classes into separate files.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top