By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,584 Members | 1,750 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,584 IT Pros & Developers. It's quick & easy.

Overcoming C# limitations

P: n/a
Hi,

I've recently encountered some design problems due to the language
limitations of C#.
Here are the scenarios:

1. Suppose I have a numerous number of functions that I would like to
add an optional parameter to. Since C# does not support optional
parameters, I would have to duplicate all these functions and override
each of them with another parameter. Is this really necessary?? Is it
just me or is the result kind of ugly?

2. In C++ I could have defined a macro to instantiate an object and
then make a method call. For example:
#define MY_FUNC(x) MyObj a; a.func(x);
This would have been useful since I could use this macro in any scope
knowing that the destructor of MyObj (or instance a) will be called at
the end of the scope without explictly calling any function. For
example:
void Foo()
{
MY_FUNC(3);
.... more code....
} <-- destructor of MyObj would be called here

Now back to C#, the preprocessor is very limited so I cannot define
that macro.
If I encapsulate these two lines of code in a method I obviously loose
this advantage, and so I'm left copying and pasting that block of code
wherever it's needed.

I know this may sound stupid, it's just being used to C++, these
problems seem rather odd.
If I'm missing a cleaner way to do this please let me know.

Thanks,

Danny

Jun 18 '06 #1
Share this Question
Share on Google+
28 Replies


P: n/a
On 18 Jun 2006 15:27:32 -0700, "Danny Liberty" <dl******@gmail.com>
wrote:
Hi,

I've recently encountered some design problems due to the language
limitations of C#.
Here are the scenarios:

1. Suppose I have a numerous number of functions that I would like to
add an optional parameter to. Since C# does not support optional
parameters, I would have to duplicate all these functions and override
each of them with another parameter. Is this really necessary?? Is it
just me or is the result kind of ugly?


You don't have to duplicate the methods. Place all the code in the
method call with the most parameters, and have the other methods call
that one, like this.

public int MyFunc(string s,int optional)
{
// Code goes here ...
}

public int MyFunc(string s)
{
MyFunc(s,10); //Assuming default value for optional is 10
}

--
Marcus Andrén
Jun 18 '06 #2

P: n/a
Hi Danny,
1. Suppose I have a numerous number of functions that I would like to
add an optional parameter to. Since C# does not support optional
parameters, I would have to duplicate all these functions and override
each of them with another parameter. Is this really necessary?? Is it
just me or is the result kind of ugly?
This subject has been brought up quite a bit, and there seems to be some
ambivalence about it even at Microsoft. However, in the end, they had to
make a decision, and decided against it. I remember reading a blog entry by
one of the .Net developers at Microsoft some time ago, but don't remember
exactly where it is. There is some discussion of it here
(http://weblogs.asp.net/jcogley/archi...08/239646.aspx) as well as a
link to a video in which several of the .Net developers talk about it.
Perhaps someone else remembers the blog entry I have forgotten about.
2. In C++ I could have defined a macro to instantiate an object and
then make a method call. For example:
#define MY_FUNC(x) MyObj a; a.func(x);
This would have been useful since I could use this macro in any scope
knowing that the destructor of MyObj (or instance a) will be called at
the end of the scope without explictly calling any function. For
example:
There is no provision in the C# specification for either macros or inline
functions. I can certainly understand the problem with macros (although I'm
sure it is not insurmountable), which are not type-safe, but I do wish there
was a provision for inline functions, which are type-safe in C++, and would
not, I believe, pose any problems in the C# spec. So, I'm on your side on
that one. As for the first, well, I can understand the ambivalence, and at
some point we all have to fish or cut bait, so I'm not complaining about it.

--
HTH,

Kevin Spencer
Microsoft MVP
Professional Chicken Salad Alchemist

I recycle.
I send everything back to the planet it came from.
"Danny Liberty" <dl******@gmail.com> wrote in message
news:11*********************@g10g2000cwb.googlegro ups.com... Hi,

I've recently encountered some design problems due to the language
limitations of C#.
Here are the scenarios:

1. Suppose I have a numerous number of functions that I would like to
add an optional parameter to. Since C# does not support optional
parameters, I would have to duplicate all these functions and override
each of them with another parameter. Is this really necessary?? Is it
just me or is the result kind of ugly?

2. In C++ I could have defined a macro to instantiate an object and
then make a method call. For example:
#define MY_FUNC(x) MyObj a; a.func(x);
This would have been useful since I could use this macro in any scope
knowing that the destructor of MyObj (or instance a) will be called at
the end of the scope without explictly calling any function. For
example:
void Foo()
{
MY_FUNC(3);
.... more code....
} <-- destructor of MyObj would be called here

Now back to C#, the preprocessor is very limited so I cannot define
that macro.
If I encapsulate these two lines of code in a method I obviously loose
this advantage, and so I'm left copying and pasting that block of code
wherever it's needed.

I know this may sound stupid, it's just being used to C++, these
problems seem rather odd.
If I'm missing a cleaner way to do this please let me know.

Thanks,

Danny

Jun 18 '06 #3

P: n/a
Marcus Andrén wrote:
On 18 Jun 2006 15:27:32 -0700, "Danny Liberty" <dl******@gmail.com>
wrote:
Hi,

I've recently encountered some design problems due to the language
limitations of C#.
Here are the scenarios:

1. Suppose I have a numerous number of functions that I would like to
add an optional parameter to. Since C# does not support optional
parameters, I would have to duplicate all these functions and
override each of them with another parameter. Is this really
necessary?? Is it just me or is the result kind of ugly?


You don't have to duplicate the methods. Place all the code in the
method call with the most parameters, and have the other methods call
that one, like this.

public int MyFunc(string s,int optional)
{
// Code goes here ...
}

public int MyFunc(string s)
{
MyFunc(s,10); //Assuming default value for optional is 10
}


.... and while this isn't as elegant as optional parameters, in terms of the
amount of source text you have to write, at runtime it's pretty much a wash,
and perhaps actually better. With optional parameters, the compiler has to
instantiate the optional parameters at every call site, while the forwarding
function instantiates the optional parameters only once. While there's no
guarantee, it's entirely possible that the JIT will inline the forwarding
function, resulting in exactly the same performance at runtime as you'd have
with the C++ solution.

-cd
Jun 18 '06 #4

P: n/a
Danny,
In addition to what Kevin and Carl suggested, you also have the option to
create an "optional parameter" object array using the C# params keyword, and
handle checking these and handling same in the method body.

Regarding macro definitions, can't suggest anything there. "It is what it is".

Not having spent too much time in the C++ world (only enough to become
dangerous) I find C# to be remarkably "non restrictive" in terms of what I
can accomplish with it.
Peter

--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com


"Danny Liberty" wrote:
Hi,

I've recently encountered some design problems due to the language
limitations of C#.
Here are the scenarios:

1. Suppose I have a numerous number of functions that I would like to
add an optional parameter to. Since C# does not support optional
parameters, I would have to duplicate all these functions and override
each of them with another parameter. Is this really necessary?? Is it
just me or is the result kind of ugly?

2. In C++ I could have defined a macro to instantiate an object and
then make a method call. For example:
#define MY_FUNC(x) MyObj a; a.func(x);
This would have been useful since I could use this macro in any scope
knowing that the destructor of MyObj (or instance a) will be called at
the end of the scope without explictly calling any function. For
example:
void Foo()
{
MY_FUNC(3);
.... more code....
} <-- destructor of MyObj would be called here

Now back to C#, the preprocessor is very limited so I cannot define
that macro.
If I encapsulate these two lines of code in a method I obviously loose
this advantage, and so I'm left copying and pasting that block of code
wherever it's needed.

I know this may sound stupid, it's just being used to C++, these
problems seem rather odd.
If I'm missing a cleaner way to do this please let me know.

Thanks,

Danny

Jun 18 '06 #5

P: n/a
"Danny Liberty" <dl******@gmail.com> wrote in message
news:11*********************@g10g2000cwb.googlegro ups.com...

1. Suppose I have a numerous number of functions that I would like to
add an optional parameter to.
You -might- reevaluate the design to see if this is really the best way to
accomplish what you want. Mind you, I'm not saying it's necessarily bad, but
it might be a design "smell" that could be fixed by (for example)
introducing a new class. Just a possibility.
2. In C++ I could have defined a macro to instantiate an object and
then make a method call. For example:
#define MY_FUNC(x) MyObj a; a.func(x);
I would just do

new MyObj().func(x);
This would have been useful since I could use this macro in any scope
knowing that the destructor of MyObj (or instance a) will be called at
the end of the scope without explictly calling any function.


Since there's no reference to the object, it will be garbage-collected at
the next opportunity. If the class -must- have destructor semantics (because
it's holding a database connection, e.g.), look into implementing
IDisposable. Otherwise, don't worry about destructors in C#. The main reason
we cared about them in C++ is because we had no garbage collection.

Again, however, I would suggest that -possibly- it's a smell to instantiate
a class just to call one method on it, and then dump the object. Of course,
I could only comment intelligently about that after seeing the actual code
in question.

///ark
Jun 19 '06 #6

P: n/a
Mark Wilden wrote:
e.g.), look into implementing IDisposable. Otherwise, don't worry
about destructors in C#. The main reason we cared about them in C++
is because we had no garbage collection.


Actually, that's largely untrue, especially in "modern style" C++. Modern
C++ practice makes extensive use of object lifetime to define program
behavior. The lack of deterministic object lifetime in C# (other than with
a coding convention like using + IDisposable) makes it difficult to adapt
many successful C++ programming techniques to C#.

While I haven't been able to spend much time writing .NET code in C++/CLI,
one of the things I'd hope to capitalize on is the ability to use
deterministic object lifetime to automate manual conventions like
IDisposable while still generating 100% verifiable managed code.

-cd
Jun 19 '06 #7

P: n/a
Danny Liberty wrote:
2. In C++ I could have defined a macro to instantiate an object and
then make a method call. For example:
#define MY_FUNC(x) MyObj a; a.func(x);
This would have been useful since I could use this macro in any scope
knowing that the destructor of MyObj (or instance a) will be called at
the end of the scope without explictly calling any function. For
example:
void Foo()
{
MY_FUNC(3);
.... more code....
} <-- destructor of MyObj would be called here


um... You want to hid the call to the ctor, and then have significant
action in the dtor. Forgive me, but I'm really glad I don't have to
maintain your code....

Jun 19 '06 #8

P: n/a
<ja**********@gmail.com> wrote in message
news:11**********************@p79g2000cwp.googlegr oups.com...
um... You want to hid the call to the ctor, and then have significant
action in the dtor. Forgive me, but I'm really glad I don't have to
maintain your code....


My thoughts exactly, having the creation of the object hidden like this just
obfuscates the code. IMO, a modern oop language is better off without being
able to #define macros. We'd be much better off with an attribute that could
tell the compiler to inline a function (assuming something like that doesn't
already exist).

Michael
Jun 19 '06 #9

P: n/a
"Carl Daniel [VC++ MVP]" <cp*****************************@mvps.org.nospam >
wrote in message news:uF**************@TK2MSFTNGP04.phx.gbl...
Mark Wilden wrote:
e.g.), look into implementing IDisposable. Otherwise, don't worry
about destructors in C#. The main reason we cared about them in C++
is because we had no garbage collection.


Actually, that's largely untrue, especially in "modern style" C++. Modern
C++ practice makes extensive use of object lifetime to define program
behavior. The lack of deterministic object lifetime in C# (other than
with a coding convention like using + IDisposable) makes it difficult to
adapt many successful C++ programming techniques to C#.


No, the same RAII technique in C++ is directly transferable to IDisposable.
And far from being a coding convention, IDisposable has the language support
of the 'using' statement.

We -had- to care about object destruction - of all dynamic objects - in C++,
because no one else would do it for us. The cases - in C++ or C# - where an
object must be destroyed / disposed deterministically are very much a
minority.
Jun 19 '06 #10

P: n/a
Mark Wilden wrote:
"Carl Daniel [VC++ MVP]"
<cp*****************************@mvps.org.nospam > wrote in message
news:uF**************@TK2MSFTNGP04.phx.gbl...
Mark Wilden wrote:
e.g.), look into implementing IDisposable. Otherwise, don't worry
about destructors in C#. The main reason we cared about them in C++
is because we had no garbage collection.
Actually, that's largely untrue, especially in "modern style" C++. Modern
C++ practice makes extensive use of object lifetime to define
program behavior. The lack of deterministic object lifetime in C#
(other than with a coding convention like using + IDisposable)
makes it difficult to adapt many successful C++ programming
techniques to C#.


No, the same RAII technique in C++ is directly transferable to
IDisposable. And far from being a coding convention, IDisposable has
the language support of the 'using' statement.


No, IDisposable is a coding convention with minimal language support that
puts the burden on the _user_ of the class to use it right, rather than on
the _designer_ of the class. The language support is nothing but thin
syntactic sugar.
We -had- to care about object destruction - of all dynamic objects - in C++, because no one else would do it for us.
You're unnecessarily mixing two concepts here: object lifetime and memory
lifetime. GC handles memory lifetime well, but creates problems with
non-deterministic object lifetime.
The cases - in C++ or
C# - where an object must be destroyed / disposed deterministically
are very much a minority.


I would disagree with that for modern C++ practice. If you program "in the
style of the STL", use smart pointers, etc, you rarely deal in object
lifetimes directly. I've scarcely written a call to the delete operator in
C++ in the last 5 years. Instead, having well-defined object lifetimes
allows you to delegate all of that to a few simple components.

The questsion is really not about whether an object _must_ be destroyed at a
given time. Rather, it's about the value of knowing with certainly when an
object will be destroyed. Objects like stream classes that have handles
open, etc, are indeed a minority among classes, but neither are they the
primary beneficiaries of having well defined object lifetimes.

-cd
Jun 19 '06 #11

P: n/a
Mark Wilden wrote:
"Carl Daniel [VC++ MVP]" <cp*****************************@mvps.org.nospam >
wrote in message news:uF**************@TK2MSFTNGP04.phx.gbl...
[...]

No, the same RAII technique in C++ is directly transferable to IDisposable.
And far from being a coding convention, IDisposable has the language support
of the 'using' statement.
If you use the object in a function block only.
But if the object is held in several lists and has to be destroyed
(disposed) if it has been removed from the last list holding file
objects, then you cannot implement this in C# easily.
Doesn't mean that I generally favor reference counting over garbage
collection, but sometimes I find it quite useful. Especially when the
objects are used by different threads.
We -had- to care about object destruction - of all dynamic objects - in C++,
because no one else would do it for us. The cases - in C++ or C# - where an
object must be destroyed / disposed deterministically are very much a
minority.


IMHO most of the objects holding unmanaged resources need to be
destroyed deterministically.

E.g. if you have a File object that is stored in multiple lists and used
by different threads. If the last thread removes it from the list and if
the object isn't used anymore the file shall be close immediately, so
that it isn't locked anymore.
I don't know how to accomplish this easily, without reference counting.
In C# I could implement a wrapper object, which has a close function,
which decreases a close counter and calls the Close method of the
embedded File object, if it reaches zero. But I have to use a try /
finally block and call the Close method in the finally block in C# or
instantiate another wrapper object in C#, which allows me to use the
"using" statement.

I don't care about the memory resources, these are handled quite well by
the garbage collection. But if I have to keep track of my unmanaged
resources, I cannot think of a simple solution in C#. :-(

Andre
Jun 19 '06 #12

P: n/a
> 2. In C++ I could have defined a macro to instantiate an object and
then make a method call. For example:
#define MY_FUNC(x) MyObj a; a.func(x);
This would have been useful since I could use this macro in any scope
knowing that the destructor of MyObj (or instance a) will be called at
the end of the scope without explictly calling any function. For
example:
void Foo()
{
MY_FUNC(3);
.... more code....
} <-- destructor of MyObj would be called here

Now back to C#, the preprocessor is very limited so I cannot define
that macro.


Maybe I'm just being thick about this, but what's wrong with writing a
static method in MyObj:

public static void MyFunc(int x)
{
MyObj a;
a.func(x);
}

Then all you have to say is: MyObj.MyFunc(3)

This idiom is used from time to time in the .NET Framework.

The only thing that this _doesn't_ let you do that the C++ idiom lets
you do is this:

MY_FUNC(3);
.... more code that uses "a" ...

which is really disgusting anyway, and IMHO one of the reasons why
using macros like this sucked in C/C++. Responsible use of the macro,
i.e. refraining from using variables declared within the macro outside
of the macro seems to me to be more-or-less equivalent to a static
method in C#.

Of course, there may be subtleties that I'm missing here....

Jun 19 '06 #13

P: n/a
"Bruce Wood" <br*******@canada.com> wrote in message
news:11**********************@c74g2000cwc.googlegr oups.com...
Maybe I'm just being thick about this, but what's wrong with writing a
static method in MyObj:

public static void MyFunc(int x)
{
MyObj a;
a.func(x);
}


The code in "func" doesn't seem to care about the state that MyObj starts in
or the state that it is left in. So the function is probably stateless and
should probably just be static anyway.

Michael
Jun 19 '06 #14

P: n/a
On 18 Jun 2006 15:27:32 -0700, "Danny Liberty" <dl******@gmail.com>
wrote:
1. Suppose I have a numerous number of functions that I would like to
add an optional parameter to. Since C# does not support optional
parameters, I would have to duplicate all these functions and override
each of them with another parameter. Is this really necessary?? Is it
just me or is the result kind of ugly?
There's the params mechanism that works like varargs in C. But yeah,
optional parameters don't exist. The CLR doesn't support them so
runtime linking gets iffy with languages that do support them, like
Visual Basic. The default value is placed in the calling assembly at
compile time, so it won't change even if the assembly that holds the
called method is replaced with a newer version. That sucks.
2. In C++ I could have defined a macro to instantiate an object and
then make a method call. For example:
#define MY_FUNC(x) MyObj a; a.func(x);


I just want to say how extremely happy I am that the C# team decided
to use a limited preprocessor that prevents this sort of pointless
obfuscation. A macro that looks like a function call but actually
allocates an object? WTF? Why not define a static method since you
evidently don't use any specific state data?
--
http://www.kynosarges.de
Jun 19 '06 #15

P: n/a
"Carl Daniel [VC++ MVP]" <cp*****************************@mvps.org.nospam >
wrote in message news:uu****************@TK2MSFTNGP04.phx.gbl...

No, IDisposable is a coding convention with minimal language support that
puts the burden on the _user_ of the class to use it right, rather than on
the _designer_ of the class. The language support is nothing but thin
syntactic sugar.
Well, OK, but before you said it was just a coding convention. auto_ptr<> is
a coding convention. IDisposable and 'using' is built into the language.
And if the _user_ is smart enough to use FxCop, it's a no-brainer to conform
to. One could say that destructors are just as much "syntactic sugar."
We -had- to care about object destruction - of all dynamic objects -

in C++, because no one else would do it for us.


You're unnecessarily mixing two concepts here: object lifetime and memory
lifetime.


In C++, they're identical - that's why I mentioned it WRT C++.
GC handles memory lifetime well, but creates problems with
non-deterministic object lifetime.
What problems do you refer to? The ones that IDisposable solves, or the ones
when you don't implement IDisposable and don't use 'using' and don't use
FxCop?
I would disagree with that for modern C++ practice. If you program "in
the style of the STL", use smart pointers, etc, you rarely deal in object
lifetimes directly. I've scarcely written a call to the delete operator
in C++ in the last 5 years. Instead, having well-defined object lifetimes
allows you to delegate all of that to a few simple components.
I have to admit that my C++ experience ended in 2000, when auto_ptr<> was
still somewhat controversial, so you may have a point. I don't know if smart
pointers are as widely used today in the C++ world as 'using' is in the C#
world.
The questsion is really not about whether an object _must_ be destroyed at
a given time. Rather, it's about the value of knowing with certainly when
an object will be destroyed. Objects like stream classes that have
handles open, etc, are indeed a minority among classes, but neither are
they the primary beneficiaries of having well defined object lifetimes.


I don't think I quite follow you there. All I can tell you is that such
certainty doesn't seem to be very important in C# programming. But when it
is, there are language constructs, coding conventions, and automated tools
to support it.
Jun 19 '06 #16

P: n/a
"Andre Kaufmann" <an****************@t-online.de> wrote in message
news:uG**************@TK2MSFTNGP05.phx.gbl...

No, the same RAII technique in C++ is directly transferable to
IDisposable. And far from being a coding convention, IDisposable has the
language support of the 'using' statement.
If you use the object in a function block only.
But if the object is held in several lists and has to be destroyed
(disposed) if it has been removed from the last list holding file objects,
then you cannot implement this in C# easily.


That's a good point. However, I think it's rare enough that support for it
doesn't need to be included in the language itself. (By "rare," I don't mean
that it's not done, but that it's done far, far less frequently than simpler
scenarios.)
IMHO most of the objects holding unmanaged resources need to be destroyed
deterministically.
Yes, but I was comparing them to the sum of all objects that are destroyed.
I don't care about the memory resources, these are handled quite well by
the garbage collection. But if I have to keep track of my unmanaged
resources, I cannot think of a simple solution in C#. :-(


Reference counting -is- a simple solution. But much less simpler than C++'s
destructors, I admit.
Jun 19 '06 #17

P: n/a
On Mon, 19 Jun 2006 13:19:57 +1000, "Michael C" <no****@nospam.com>
wrote:
My thoughts exactly, having the creation of the object hidden like this just
obfuscates the code. IMO, a modern oop language is better off without being
able to #define macros. We'd be much better off with an attribute that could
tell the compiler to inline a function (assuming something like that doesn't
already exist).


Very simple methods are inlined automatically by the JIT compiler.
I think the conditions were something like at most one control
statement, throws no exceptions, and some code size limit.
--
http://www.kynosarges.de
Jun 19 '06 #18

P: n/a
Yes of course, but I wasn't talking about the actual implementation,
just the duplication of the methods itself that seems to dirty the
code.

Marcus Andrén wrote:
On 18 Jun 2006 15:27:32 -0700, "Danny Liberty" <dl******@gmail.com>
wrote:
Hi,

I've recently encountered some design problems due to the language
limitations of C#.
Here are the scenarios:

1. Suppose I have a numerous number of functions that I would like to
add an optional parameter to. Since C# does not support optional
parameters, I would have to duplicate all these functions and override
each of them with another parameter. Is this really necessary?? Is it
just me or is the result kind of ugly?


You don't have to duplicate the methods. Place all the code in the
method call with the most parameters, and have the other methods call
that one, like this.

public int MyFunc(string s,int optional)
{
// Code goes here ...
}

public int MyFunc(string s)
{
MyFunc(s,10); //Assuming default value for optional is 10
}

--
Marcus Andrén


Jun 19 '06 #19

P: n/a
Nothing is hidden here. Every object's destructor is called when it
leaves scope. You might as well have defined a CString and have a
"hidden" destructor as you call it run when the function leaves. It's a
very simple design concept of programing in C++. I'm not debating
wether C# has done a better job, I'm sure it has. I was just asking if
I could somehow mimic some C++ features that in my opinion, make things
a bit easier to do.
ja**********@gmail.com wrote:
Danny Liberty wrote:
2. In C++ I could have defined a macro to instantiate an object and
then make a method call. For example:
#define MY_FUNC(x) MyObj a; a.func(x);
This would have been useful since I could use this macro in any scope
knowing that the destructor of MyObj (or instance a) will be called at
the end of the scope without explictly calling any function. For
example:
void Foo()
{
MY_FUNC(3);
.... more code....
} <-- destructor of MyObj would be called here


um... You want to hid the call to the ctor, and then have significant
action in the dtor. Forgive me, but I'm really glad I don't have to
maintain your code....


Jun 19 '06 #20

P: n/a
> Very simple methods are inlined automatically by the JIT compiler.

I had wondered if that might be the case. Still, it might be nice to be able
to explicitly declare a function as "inline" in order to make sure, or to
make it clear in the code.

--
HTH,

Kevin Spencer
Microsoft MVP
Professional Chicken Salad Alchemist

I recycle.
I send everything back to the planet it came from.

"Chris Nahr" <ch************@kynosarges.de> wrote in message
news:kk********************************@4ax.com...
On Mon, 19 Jun 2006 13:19:57 +1000, "Michael C" <no****@nospam.com>
wrote:
My thoughts exactly, having the creation of the object hidden like this
just
obfuscates the code. IMO, a modern oop language is better off without
being
able to #define macros. We'd be much better off with an attribute that
could
tell the compiler to inline a function (assuming something like that
doesn't
already exist).


Very simple methods are inlined automatically by the JIT compiler.
I think the conditions were something like at most one control
statement, throws no exceptions, and some code size limit.
--
http://www.kynosarges.de

Jun 19 '06 #21

P: n/a
I agree. And if the method can be in-lined, the compiler will do so (based
on some rules).

--
William Stacey [MVP]

"Chris Nahr" <ch************@kynosarges.de> wrote in message
news:9t********************************@4ax.com...
| On 18 Jun 2006 15:27:32 -0700, "Danny Liberty" <dl******@gmail.com>
| wrote:
|
| >1. Suppose I have a numerous number of functions that I would like to
| >add an optional parameter to. Since C# does not support optional
| >parameters, I would have to duplicate all these functions and override
| >each of them with another parameter. Is this really necessary?? Is it
| >just me or is the result kind of ugly?
|
| There's the params mechanism that works like varargs in C. But yeah,
| optional parameters don't exist. The CLR doesn't support them so
| runtime linking gets iffy with languages that do support them, like
| Visual Basic. The default value is placed in the calling assembly at
| compile time, so it won't change even if the assembly that holds the
| called method is replaced with a newer version. That sucks.
|
| >2. In C++ I could have defined a macro to instantiate an object and
| >then make a method call. For example:
| >#define MY_FUNC(x) MyObj a; a.func(x);
|
| I just want to say how extremely happy I am that the C# team decided
| to use a limited preprocessor that prevents this sort of pointless
| obfuscation. A macro that looks like a function call but actually
| allocates an object? WTF? Why not define a static method since you
| evidently don't use any specific state data?
| --
| http://www.kynosarges.de
Jun 19 '06 #22

P: n/a
Mark Wilden wrote:
The questsion is really not about whether an object _must_ be
destroyed at a given time. Rather, it's about the value of knowing
with certainly when an object will be destroyed. Objects like
stream classes that have handles open, etc, are indeed a minority
among classes, but neither are they the primary beneficiaries of
having well defined object lifetimes.


I don't think I quite follow you there. All I can tell you is that
such certainty doesn't seem to be very important in C# programming.
But when it is, there are language constructs, coding conventions,
and automated tools to support it.


Yes, there are. IMO the facilities in C++ are better.

-cd
Jun 19 '06 #23

P: n/a
"Carl Daniel [VC++ MVP]" <cp*****************************@mvps.org.nospam >
wrote in message news:eT**************@TK2MSFTNGP04.phx.gbl...

I don't think I quite follow you there. All I can tell you is that
such certainty doesn't seem to be very important in C# programming.
But when it is, there are language constructs, coding conventions,
and automated tools to support it.


Yes, there are. IMO the facilities in C++ are better.


This discussion has certainly made me understand that viewpoint better. And
to agree that, for the specific cases under discussion, you're right -- C++
is better.
Jun 19 '06 #24

P: n/a

Chris Nahr wrote:
On 18 Jun 2006 15:27:32 -0700, "Danny Liberty" <dl******@gmail.com>
wrote:

I just want to say how extremely happy I am that the C# team decided
to use a limited preprocessor that prevents this sort of pointless
obfuscation. A macro that looks like a function call but actually
allocates an object? WTF? Why not define a static method since you
evidently don't use any specific state data?


Macros we're EXTREMELY useful in C.
In C++ they were often used, but more often abused (myself included on
occasion) by doing exactly the type of thing that Danny is trying.

I do miss them occasionally in C# although mainly for things like
declaring a constant value instead of declaring a constant type.

On the whole though I think we're probably better off without them.
There is a lot of C# code around as it is that is badly written, badly
laid out and almost impossible to follow. Macros would make it 10 times
worse!
Paul

Jun 19 '06 #25

P: n/a
"Danny Liberty" <dl******@gmail.com> wrote in message
news:11**********************@u72g2000cwu.googlegr oups.com...
Nothing is hidden here. Every object's destructor is called when it
leaves scope. You might as well have defined a CString and have a
"hidden" destructor as you call it run when the function leaves. It's a
very simple design concept of programing in C++. I'm not debating
wether C# has done a better job, I'm sure it has. I was just asking if
I could somehow mimic some C++ features that in my opinion, make things
a bit easier to do.


Easier for you or the person who takes over your job?

Michael
Jun 19 '06 #26

P: n/a
Mark Wilden wrote:
"Carl Daniel [VC++ MVP]"
<cp*****************************@mvps.org.nospam > wrote in message
news:eT**************@TK2MSFTNGP04.phx.gbl...

I don't think I quite follow you there. All I can tell you is that
such certainty doesn't seem to be very important in C# programming.
But when it is, there are language constructs, coding conventions,
and automated tools to support it.


Yes, there are. IMO the facilities in C++ are better.


This discussion has certainly made me understand that viewpoint
better. And to agree that, for the specific cases under discussion,
you're right -- C++ is better.


btw - don't get me wrong. I love C# and do almost 100% of my programming in
it. But there are things about C++ that I still like better - there's still
room for more cross-polination between these languages to the betterment of
both.

-cd
Jun 20 '06 #27

P: n/a
Carl Daniel [VC++ MVP] wrote:
Marcus Andrén wrote:
On 18 Jun 2006 15:27:32 -0700, "Danny Liberty" <dl******@gmail.com>
wrote:
Hi,

I've recently encountered some design problems due to the language
limitations of C#.
Here are the scenarios:

1. Suppose I have a numerous number of functions that I would like to
add an optional parameter to. Since C# does not support optional
parameters, I would have to duplicate all these functions and
override each of them with another parameter. Is this really
necessary?? Is it just me or is the result kind of ugly?

You don't have to duplicate the methods. Place all the code in the
method call with the most parameters, and have the other methods call
that one, like this.

public int MyFunc(string s,int optional)
{
// Code goes here ...
}

public int MyFunc(string s)
{
MyFunc(s,10); //Assuming default value for optional is 10
}


.... and while this isn't as elegant as optional parameters, in terms of the
amount of source text you have to write, at runtime it's pretty much a wash,
and perhaps actually better. With optional parameters, the compiler has to
instantiate the optional parameters at every call site, while the forwarding
function instantiates the optional parameters only once. [..]


I made a proposal in this newsgroup a few days ago "[Proposal] Named and
Optional Parameters with Default Values", which would solve the problem
very elagant and with no change of the clr.

Although C# does not support this at this time with short syntax (but I
hope it will do so at a later time), it is possible to use the
underlaying implementation as a good solution is some cases where it
might fit.
The basic idea is to use a second class or struct as a parameter object
which already has the default values and you assign only the
parameter-properties you actually need and pass the object into your method:

-------- my posting --------

I got a similar idea a couple of months ago, but now this one will require
no change to the clr, is relatively easy to implement and would be a great
addition to C# 3.0 :)

so here we go..

To make things simpler and better readable I'd make all default parameters
named parameters so that you can decide for yourself which one to pass and
which not, rather than relying on massively overlaoded methods which
hopefully provide the best overload for you, for example the Image.DrawImage
method has 20 overloads.

I propose a syntax like the following:

public void Open(string path, AccessMode mode = AccessMode.Read,
int bufferSize=1024)
{
// ...
}

As you can see, path is a regular parameter which cannot be omitted, whereas
Mode and BufferSize provide default values and can be omitted when calling
the method.
Named parameters can only be declared behind all regular parameters and if
you have params parameters (variable parameterlist) is must be declared at
the end of the parameterlist. Although you can omit the named parameters if
you pass them they should appear in the same order as they were declared for
better readability.

You could call the example method like the following:

Open("text.txt", $mode=AccessMode.Write, $bufferSize=512);
Open("text.txt", $bufferSize=512);
Open("text.txt", $mode=AccessMode.Write);
Open("text.txt");

Note that an $ sign has to appear before all named parameter so that you
have no naming conflicts with other variables in the callers context.

Additionally there can not be more that one method with the same name and
the same regular parameters to avoid ambiguity, so:

Foo(int i, string a="");
Foo(int i, double f=1.0f);

Would not be allowed because the call Foo(100) could not be resolved.

How will it work?
----------------------------

the following method:

public void Open(string path, AccessMode mode = AccessMode.Read, int
bufferSize=1024)
{
// ...
}

would generate the following code:

public struct OpenParams
{
public AccessMode mode;
public int bufferSize;

// because we cannot have parameterless ctors in structs
public static OpenParams DefaultValues
{
get{
OpenParams instance = new OpenParams();
instance.mode = AccessMode.Read;
instance.bufferSize=1024;
return instance;
}
}
}

public void Open(string path, ref OpenParams parms)
{
// ...
}

and the call:

Open("text.txt", $bufferSize=512);

is compiled as:

OpenParams parms = OpenParams.DefaultValues;
parms.bufferSize=512;
Open("text.txt", ref parms);
Jun 20 '06 #28

P: n/a
Of course something is hidden. Let's review your original example:
#define MY_FUNC(x) MyObj a; a.func(x);
void Foo()
{
MY_FUNC(3);
.... more code....
}

Here you are creating & destroying a MyObj, and apparently, the timing
of the destruction is important to the functioning of this routine, and
yet MyObj never appears in the code to Foo(). What about the line
"MY_FUNC(3)" would give a person any clue that an object is being
create there?
Danny Liberty wrote:
Nothing is hidden here. Every object's destructor is called when it
leaves scope. You might as well have defined a CString and have a
"hidden" destructor as you call it run when the function leaves. It's a
very simple design concept of programing in C++. I'm not debating
wether C# has done a better job, I'm sure it has. I was just asking if
I could somehow mimic some C++ features that in my opinion, make things
a bit easier to do.


Jun 22 '06 #29

This discussion thread is closed

Replies have been disabled for this discussion.