Func<int> and Func<int,int>

P

Piotrekk

Hi

I have a question which was puzzling me today.


1 static void Main(string[] args)
2 {
3 Foo(delegate { return x; });
4 }
5
6 static void Foo(Func<int,int> action)
7 {
8 Console.WriteLine("I suspect the anonymous method...");
9 }

The argument of Foo can be either Func<int> or Func<int>. I have no
idea why. We are not passing any arguments in line 3. What does the
compiler do in this case?

Kind Regards
Piotr Ko³odziej
 
M

Michael C

Peter Duniho said:
What does "either Func<int> or Func<int>" mean? Aren't the two the same?

Surely you realise he meant Func<int> and Func<int, int>. Why do you always
play dumb like this? I've seen you do this many times.

Michael
 
P

Peter Morris

Surely you realise he meant Func said:
always play dumb like this? I've seen you do this many times.

I thought it was likely due to the subject, however, the additional
information didn't result in the question making sense to me :)
 
P

Piotrekk

In line 6 change Func<int> to Func<int,int>. It will compile. How then
if in line 3 we are not passing any arguments.
 
P

Piotrekk

In line 6 change Func<int> to Func<int,int>. It will compile. How then
if in line 3 we are not passing any arguments.

I can say more. You can change Func<int> in line 6 even to
Func<int,int,int> and it will still compile.
 
P

Peter Morris

Sorry, I have only been awake for 10 minutes :-D

static void Main(string[] args)
{
Foo( a => a+1);
}

static void Foo(Func<int, int> action)
{
Console.WriteLine("Result is " + action(1).ToString());
}


This code returns "Result is 2". This is obviously because the lambda takes
the 1 and returns +1, so you get 2.


static void Main(string[] args)
{
Foo(delegate { return 1; });
}

static void Foo(Func<int, int> action)
{
Console.WriteLine("I suspect the anonymous method..." +
action(1).ToString());
}

This code returns "Result is 1". This is because the anonymous method is
ignoring the parameter you pass.

Therefore
Foo( a => a+1);
is the same as
Foo(delegate(int a) { return a + 1; });

and
Foo(delegate { return 1; });
is functionally the same as
Foo(delegate(int a) { return 1; });
or as a short-cut the argument may be ignored...
Foo(delegate { return 1; });

The argument is still passed, you just aren't using it. The following code:

Foo(a => a + 1);
Foo(delegate(int a) { return a + 1; });
Foo (a => 1);
Foo(delegate { return 1; });

viewed in Reflector is

private static void Main(string[] args)
{
Foo(delegate (int a) {
return a + 1;
});
Foo(delegate (int a) {
return a + 1;
});
Foo(delegate (int a) {
return 1;
});
//Note the parameter is not referenced
Foo(delegate {
return 1;
});
}
 
M

Michael C

Peter Duniho said:
I realize no such thing.

You must be pretty silly then considering it's the subject line.
I'm not "playing dumb".

I was going to make a smart arse comment that you are dumb but I know you're
not.
The fact is, there is no reliable way to make an assumption about what
someone _meant_ to write when they write something else.

It is fairly obvious he was asking why it makes no difference if he uses
Func said:
For example, in this particular case, even if I replace "Func<int>" with
"Func<int, int>", what he wrote still makes no sense. So why in the
world, if I were going to make _any_ assumptions about what he meant,
assume something that is just as meaningless as what he wrote to start
with.

The question isn't that confusing really. I could infer from what he wrote
that I should 1) paste the code into vs2008 2) compile it 3) substitute
What you _have_ seen me do many times is ask for clarification when people
have not posted questions that make sense. Frankly, I don't understand
why you think this is an odd thing to do. The best way to answer a
question is to first make sure you understand it.

You seem to like pointing out when people make simple typing mistakes and
then make fun of them about it. Generally you do this subtlely so that you
can deny it if questioned (as you are doing now :)
I suggest that instead of taking me to task for something that, frankly,
is a perfectly reasonable response, if you think there is a better way to
answer the question, answer it yourself in that way. And if you can't
think of a better way to answer the question, I really don't think you've
got any justification making criticisms about the way _I_ answer the
question.

I didn't answer the question because I didn't have vs2008 in front of me. At
home I'm stuck in the 2003 world.

Michael
 
J

Joe Greer

I thought it was likely due to the subject, however, the additional
information didn't result in the question making sense to me :)

If I am not wrong, I suspect that he is surprised that it compiles. One
would normally think that the delegate would have a signature of Func<int>,
so why does it compile if the signature of Foo is Func<int, int>? It is
not intuitive to me either.

joe
 
P

Pavel Minaev

In line 6 change Func<int> to Func<int,int>. It will compile. How then
if in line 3 we are not passing any arguments.

Basically, because there is a difference between those two:

delegate() { return 1; }
delegate { return 1; }

The first one is an anonymous delegate which takes _no_ arguments and
returns an int. It is compatible with Func<int>, but not with
Func<int,int>. So:

Func<int> f1 = delegate() { return 1; } // ok
Func<int, int> f2 = delegate() { return 2; } // error

The second one is an anonymous delegate which takes _any number_ of
arguments, and doesn't use them in any way. Because of that, it is
compatible with _any_ delegate type that returns int, regardless of
number of arguments and their type. So:

Func<int> f1 = delegate { return 1; } // ok
Func<int, int> f2 = delegate { return 2; } // ok - ignore the int
argument
Func<int, int, int> f3 = delegate { return 3; } // ok - ignore both
int arguments
Func<string, int> f4 = delegate { return 4; } // ok - ignore the
string argument
...

One thing to keep in mind is that anonymous delegates and lambdas do
not have types as such - they match delegate types when used in a
context where a delegate type is involved, but the same anon
delegate / lambda can sometimes match more than one delegate type in
different contexts.
 
P

Pavel Minaev

When you provide a lambda expression or anonymous method without any  
argument list (as opposed to an empty argument list, which is not the  
same)

Now I'm genuinely curious - how do you provide a lambda expression
without an argument list, as opposed to providing an empty argument
list?
 
M

Michael C

There's nothing that suggests to me that the subject line is in fact a
suitable replacement for the text I quoted.

Surely you jest?
If you want to continue with the ad hominem attacks, feel free. But I
find them pointless and insulting.

Kinda ironic don't you think? :)))
Obvious? Not to me. After all, it _does_ make a very big difference if
he uses one or the other as the type of the expression passed to the Foo()
method.

If you made even the slightest effort to understand the question then it
would be obvious.
But then, I already pointed that out. You seem to be ignoring the fact
that even if I were to be so willing as to make assumptions as you
apparently are, that doesn't result in a question that makes any sense.

The question wasn't that unclear.
Unless the OP states one way or the other whether your assumption about
him was correct, I suppose we can leave open whether you made the right
assumption. Maybe you did in fact do so. But I am telling you flat out
that you made the wrong assumption about me. That should be the end of
it.

Hardly, I assumed you would deny it and you did.
Frankly, your "observation" is complete baloney. Again, you're making
assumptions about what I do or do not like, and about what my intent is.
And your assumptions are just plain wrong.

This assumption is based on observing many of your posts over the last
couple of years. The one when I asked about calling ToString on a null
reference was the classic case.
Then perhaps you should have just kept out of the thread altogether,
seeing as you've contributed nothing productive to it.

Perhaps I should have.

Michael
 
M

Michael C

Peter Duniho said:
I have no idea what "classic case" you're referring to, but I assure you
that whatever my reply was, it was intended only to be as helpful as I
could possibly make it.

That is quite simply rubbish. You came into the thread in your normal
insulting manner and when you realised my question wasn't quite a silly as
you wished it was you bailed. After you bailed some people came in with some
intelligent replies. This seems to be a pattern for you.
Anything else you inferred, was simply so much false assumptions, just as
you've been making here.

Sure thing pete.
As for the rest of your ad hominem-filled reply: tripe.

Snip noted.

Michael
 
M

Michael C

Peter Duniho said:
No, it's not. But, making idiotic assumptions about the motivations and
intent of someone else does seem to be a pattern with _you_.
Hardly.

Here's a hint: this is a text-based forum. The only thing you can know
for sure is what someone writes. Once you start making inferences, you're
likely to make mistakes from time to time. When you're inferring negative
things about someone else, you're being foolish. When you _post_ those
inferences as if they were established fact, then you're just being a
jerk.

That is why I haven't said anything for a full 2 years. If I was going off 1
single post then what you say might hold water but I have seen this repeated
many times.
Whatever you _think_ happened to you some time ago, you need to get over
it.

That was just one example. I have seen you repeat this many times.
It didn't happen the way you think it did, and it's really hurting your
ability to judge what's actually been written, without reading into it
something that's not there, further perpetuating your pattern of
misinterpreting what I write.

Whatever.

Michael
 
P

Peter Morris

Whatever you _think_ happened to you some time ago, you need to get over
it. It didn't happen the way you think it did, and it's really hurting
your ability to judge what's actually been written

I agree that you shouldn't infer meaning in questions too much because you
end up answering something that wasn't asked, but sometimes the question is
nearly right and it is only a little bit of work to do so correcly. Just to
add a third party independant opinion here I'd like to say that you do
sometimes come across as "Ask the question perfectly or I wont answer it",
not always, but sometimes, maybe it is because of how much of your text is
directed at pointing out the mistakes in the question? I don't have an axe
to grind :)

Just to be clear, I am not being critical, I don't know you so I don't
really care what you are like :) It is possible that you missed the
subject entirely. I initially misunderstood the question myself despite
seeing the subject. People's minds just work differently, which is a good
thing otherwise we might all be like George W Bush :-D

One last observation. It's funny how two people who appear to be disliking
a conversation so much can find it so compelling to continue it :)
 
S

Shunyata Kharg

One last observation. It's funny how two people who appear to be
That's the beauty of usenet that the off topic discussion is the most
fascinating one:)

Is there a MS equivalent of b.p.o.t? Maybe threads that skew off-topic could
carry on there ...
 
M

Michael C

Peter Duniho said:
Well, I certainly didn't expect you to agree with the statement. Pretty
hypocritical of you though, if you think I should agree with _your_
mischaracterizations of me.

I don't expect you to agree either. But maybe you will think about it and
approach the next post you see differently.
So, why choose to be a jerk now? Your inference isn't any more correct
today than it was two years ago.

I think the current conversation shows why I would think twice about
bringing it up.
I can't even remember things that happened two years ago. For you to hold
a grudge that long shows that you are absolutely, disproportionately
fixated on whatever happened.

If that makes you feel better then feel free to think that. When posting on
usenet you get to know certain people. When I saw your post to this question
I knew what to expect.
Then you have made the same mistake many times.

I think Peter Morris's reply below shows I'm not imagining it.
The fact is, I answer a lot of questions here. The fact is, many of those
questions are poorly expressed and require solicitation of additional
detail in order to answer them. Given that you seem prone to
misinterpreting such solicitations, it's not surprising that over the
years you might make the same faulty inference "many times".

If you'd spend more time answering questions instead of criticizing me,
maybe you'd have a little more empathy for the situation.

I think if you'd made the slightest effort to answer the original post in
this thread then you would have gone a long way towards answering it.
Instead you put all your effort towards not answering the question and
deliberately try to not understand it. Go back and read the original
question. It's pretty obvious if you actually try.

Michael
 
M

Michael C

Peter Duniho said:
[...]
So, why choose to be a jerk now? Your inference isn't any more correct
today than it was two years ago.

I think the current conversation shows why I would think twice about
bringing it up.

Well, given that this conversation is all about the reasons why you
_should_ think twice about bringing it up (and more often, until the urge
passes), why should that be surprising?
If that makes you feel better then feel free to think that. When posting
on
usenet you get to know certain people. When I saw your post to this
question
I knew what to expect.

Really? Even without having ever read the reply? Specifically:
[...]
I think if you'd made the slightest effort to answer the original post in
this thread then you would have gone a long way towards answering it.

I _did_ answer the question, albeit without being sure it was really what
the OP wanted/needed to know.

Had you bothered to actually _read_ what I'd written, instead of going off
on this tangent, you'd realize that.

Frankly, so far you are the only person who's posted to this thread
without having _anything_ to contribute to the OP's actual question.

I think it's time to leave it there. If you've got the point then I don't
need to go any further, if you haven't then I don't think you ever will so
no need to go any further :)

Michael
 

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