local classes

  • Thread starter Thread starter PGP
  • Start date Start date
P

PGP

I notice that local classes are not supported in C#. Could you please
discuss why this is so? Was this a bad coding practice to begin with?
 
I notice that local classes are not supported in C#. Could you please
discuss why this is so? Was this a bad coding practice to begin with?

What exactly do you mean by "local classes"? Are you talking about the
anonymous inner classes that Java has? They usually tackle a need
which is better addressed with delegates in C#.

Jon
 
What exactly do you mean by "local classes"? Are you talking about the
anonymous inner classes that Java has? They usually tackle a need
which is better addressed with delegates in C#.

Jon
Not sure about Java. In C++, they are classes that can be defined within
functions.
 
Not sure about Java. In C++, they are classes that can be defined within
functions.

And what use are they? If you could say what you normally try to
achieve with them, we can explain what you'd do in the same situation
in C#.
 
Jon Skeet said:
And what use are they? If you could say what you normally try to
achieve with them, we can explain what you'd do in the same situation
in C#.
Sure. If you will please take a look at the following example which
calculates rect areas
inside a control. If we could discuss this based on this example, it would
be helpful
for me to understand the scenario and how exactly C# approaches this.

//IPaintableRectSubscriber is an interface with one method - void
OnPaintableRect(int nIndex, const CRect& rcItem);
void CThumbNailCtrl::IteratePaintableRects(IPaintableRectsSubscriber*
pSubscriber)
{
//Calculate rect areas that need painted, call back to subscriber
pSubscriber->OnPaintableRect(nIndex, rcItem) ;
}
//
BOOL CThumbNailCtrl::OnEraseBkgnd(CDC* pDC)
{
CRect rcClient ;
GetClientRect(rcClient);
//Local class here - note that the functionality
//implemented is not of interest to any other part of my control
class CEraseBkHelper : public IPaintableRectSubscriber
{
CThumbNailCtrl& m_outer; CDC* m_pDC; CRgn m_clipRgn; CRect
m_rcClient;
public:
void OnPaintableRect(const int i, const CRect& rc)
{
m_pDC->ExcludeClipRect(&rc);//exclude painted areas from
erase.
}
}erasebkhelper(*this, pDC, rcClient);
}
//
void CThumbNailCtrl::OnPaint()
{
CPaintDC dc(this);
//Local class here - Note the different params passed in constructor
//so i can have isolated logic and again, none of this
//makes sense to anything outside this function.
class CPaintHelper : public IPaintableRectsSubscriber
{
CThumbNailCtrl& m_outer; CPaintDC& m_dc;
public:
void OnPaintableRect(const int i, const CRect& rc)
{
//do the real painting here.
}
}painthelper(*this, dc);
}

As you see from the comments, the local classes are giving me a
nice way to encapsulate my logic within the respective functions,
yet allows for subscribing to a callback from another function
or class, hence maximizing the reuse.
 
Sure. If you will please take a look at the following example which
calculates rect areas
inside a control. If we could discuss this based on this example, it would
be helpful
for me to understand the scenario and how exactly C# approaches this.

As you see from the comments, the local classes are giving me a
nice way to encapsulate my logic within the respective functions,
yet allows for subscribing to a callback from another function
or class, hence maximizing the reuse.

Right. Delegates provide the best way of encapsulating a piece of logic
in C#, particularly with anonymous methods or lambda expressions from
C# 3. In the C++ code, there's a lot of "fluff" around the real point
of the local class, which is basically just to encapsulate the logic of
the OnPaintableRect method.

The part about the different parameters being passed in the constructor
is achieved in C# 2 and 3 using captured variables of anonymous
functions.
 
Right. Delegates provide the best way of encapsulating a piece of logic
in C#, particularly with anonymous methods or lambda expressions from
C# 3. In the C++ code, there's a lot of "fluff" around the real point
of the local class, which is basically just to encapsulate the logic of
the OnPaintableRect method.

One of the seemingly "fluffy" point is that the encapsulated logic in local
classes
as opposed to distributed delegates poses a maintenance issue as one has to
track
back to the caller to really find what's affected with changes in the
delegate.
Another point is that it protects the localized logic from being reused
(read misused)
which might sound like an unforgivable sin but you might be able to relate
if you ever had to maintain code that you wrote after it has passed a couple
of hands
and back to you again.
Now there could be IDE advances in VS2008 which i am not familiar with at
this point
which might solve these issues.
 
One of the seemingly "fluffy" point is that the encapsulated logic in local
classes as opposed to distributed delegates poses a maintenance issue as one has to
track back to the caller to really find what's affected with changes in the
delegate.

What do you mean by "distributed delegates"? Do you mean the logic
being expressed in a separate place from the code using it? If so,
anonymous methods do exactly what you want.
Another point is that it protects the localized logic from being reused
(read misused)

Likewise anonymous methods.
which might sound like an unforgivable sin but you might be able to relate
if you ever had to maintain code that you wrote after it has passed a couple
of hands and back to you again.
Now there could be IDE advances in VS2008 which i am not familiar with at
this point which might solve these issues.

Anonymous methods were introduced in C# 2 (VS2005). They are largely
superceded by lambda expressions in C# 3 (VS2008) but they're still
very useful.

See http://pobox.com/~skeet/csharp/csharp2/delegates.html
 
PGP said:
One of the seemingly "fluffy" point is that the encapsulated logic in local
classes
as opposed to distributed delegates poses a maintenance issue as one has to
track
back to the caller to really find what's affected with changes in the
delegate.
Another point is that it protects the localized logic from being reused
(read misused)

My first thought when I saw the code example you provided was that a
delegate would suit your needs just fine.

Using an anonymous method, declared in the method in which you need the
delegate, addresses that need and all of the above points you make. Can
you provide an example of a C# implementation of what you're trying to
do that uses anonymous methods and yet still has the problems you
describe? It would be easier to help understand the issues you're
concerned about if you would.

Pete
 
What do you mean by "distributed delegates"? Do you mean the logic
being expressed in a separate place from the code using it? If so,
anonymous methods do exactly what you want.
Yes, Anonymous methods seems to be addressing all the concerns i
have raised. Thank you!
 
My first thought when I saw the code example you provided was that a
delegate would suit your needs just fine.

Using an anonymous method, declared in the method in which you need the
delegate, addresses that need and all of the above points you make. Can
you provide an example of a C# implementation of what you're trying to do
that uses anonymous methods and yet still has the problems you describe?
It would be easier to help understand the issues you're concerned about if
you would.

Pete

Pete,
You are right. I was still thinking about delegates when i raised the
above concerns of potential distributed code. Anonymous methods
seem to solve these issues. Thanks!

Priyesh
 
You are right. I was still thinking about delegates when i raised the
above concerns of potential distributed code. Anonymous methods
seem to solve these issues. Thanks!

Actually, (small) local classes can be useful in C++ for the reasons you
cited earlier (improved encapsulation). Few programmers ever use them
however. Unfortunately, their main (would-be) benefit isn't supported by the
language at all. You can't use them for template arguments and this is my
biggest pet peeve with the language. I find myself constantly irritated
every time I need to call a C++ algorthim (or any other template) and can't
create a small local class to work with it (a class that has specific
functionality to the function where needed and would therefore be better
defined there). It's still not clear to me why this feature was never made
available even after asking Stroustrup himself about it during a conference
a couple of years ago. His response was very terse but had something to do
with "binding" issues IIRC (whatever the details may be). The current rules
(as implemented) don't allow it since templates are effectively specialized
at the nearest global or namespace scope wherever used. IOW, the rule
precludes.their use for local classes since any use of a template
effectively specializes the template just before the function itself (so any
local class remains unknown). At least C# allows anonymous methods which can
effectively mimic some of the same functionality (thankfully, I use them
often) but a local class would be even better.
 
Actually, (small) local classes can be useful in C++ for the reasons you
cited earlier (improved encapsulation). Few programmers ever use them
however. Unfortunately, their main (would-be) benefit isn't supported by
the language at all. You can't use them for template arguments and this is
my biggest pet peeve with the language. I find myself constantly irritated
every time I need to call a C++ algorthim (or any other template) and
can't create a small local class to work with it (a class that has
specific functionality to the function where needed and would therefore be
better defined there). It's still not clear to me why this feature was
never made available even after asking Stroustrup himself about it during
a conference a couple of years ago. His response was very terse but had
something to do with "binding" issues IIRC (whatever the details may be).
The current rules (as implemented) don't allow it since templates are
effectively specialized at the nearest global or namespace scope wherever
used. IOW, the rule precludes.their use for local classes since any use of
a template effectively specializes the template just before the function
itself (so any local class remains unknown). At least C# allows anonymous
methods which can effectively mimic some of the same functionality
(thankfully, I use them often) but a local class would be even better.
Larry,
Well said about why local classes have no linkage - seriously limits
their use with templates. My feelings exactly about not being able
to write a std predicate inside the *only* function which uses it.
I havent used anonymous methods but am looking forward to it.
Still stuck with .NET 1.1 due to product issues.
Thanks for the reply. Atleast i am not the only one
trying to use local classes. Apart from the template usage
frustration, i really appreciate the support for local
classes in c++.

Priyesh
 

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

Back
Top