views:

2233

answers:

6

College friend told me about interview question that is asked in one company:

Write reasonable(=compilable) method declaration that contains as many C# keywords as possible.

  • If there are 2 or more the same keywords they are counted as one.

  • Method's body is not considered.

C# has finite number of keywords so such method must exist. What is the code of this declaration?

EDIT:

Edited to make it sound like real question.

+5  A: 

From a real-world approach, the question seems silly IMHO and certainly doesn't make good sense. I don't think a definite answer exists. My guess would be that the company was just probing to see how familiar the person is specifically with C# keywords and syntax.

Justin Pinkley
An answer must exist. There are only a limited number of C# method declarations shorter than a gzillion characters. One of those is bound to have the most number of keywords. Still a silly question, though =)
Jens
+24  A: 

As a thought exercise I came up with this, though I doubt it is definative:

protected internal new virtual unsafe void MethodName<T>(
    out int a, 
    ref int b,
    params int[] c) where T : class, new()

(Also not sure completely sure whether extern methods can be generic...)

Sounds like a completely nonsensical question to me though and I'm not sure what they were hoping to achieve by asking it.


Ah, looking that complete list of C# keywords all of the CLR types are considered to be keywords. Therefore assume the method above takes one parameter of each type - I'll be damned if I'm writing that out though...


Okay, based on the comments (I wish I hadn't started this now...)

protected internal static extern unsafe void MethodName<T, U>(
    out byte a, 
    ref char b,
    decimal c,
    double d,
    float e,
    long f,
    sbyte g,
    short h,
    uint i,
    dynamic j,
    bool k = true == false,
    T l = default(T),
    object m = null,
    int n = sizeof(ulong),
    params ushort[] o) where T : class, new()
                       where U : struct;

(Disappointingly had to loose a few things to get it to compile. Can't has a this parameter, because then the class must be static and static classes can't have protected members. Neither can we have the default values based on typeof(), is or as since they aren't compile time constants)

Martin Harris
You'd need to include all primitive types - these are keywords in C# too. Also you can add default parameter value (in C# 4) e.g. `object a = null`.
Tomas Petricek
You might as well have a parameter for every built-in C# type alias. EDIT: Make that `new static extern` for maximum coverage, I think, actually. Does `new` count as a separate keyword in the type signature and constraint?
mquander
You could add static, I think =)
Jens
you could more types instead of the int's in the parameters...
Yves M.
oh yeah, I hadn't thought of generic constraints at all. Nice one. But why not make it an extension method (can put a `this` in there on the first argument then).
jalf
@mquander, you can't specify both `virtual` and `override` on the same method -- and if you added either, you would have to remove the `static` as well as the `extern`, so it's a wash. You could add `new` though.
Joe White
@Tomas: and use `= default(T)` for another argument. `default` hasn't been used yet.
jalf
You can also add more generic parameters and add another generic constraint for each.
Johann Blais
Oh, here's another one -- if you're using C# 4, you could add `in` to the generic parameter.
Joe White
@Joe: Huh, you're right. I guess it's implied.
mquander
@Joe - you can only use `in` for contravariance on delegates and interfaces.
Mark H
There's also `unsafe`. I'm not sure if that plays well with `extern`, but you could always change `static extern` to `new virtual`.
Joe White
Also, with default parameters, you can put just about any expression in there. That gets you `as`, `is`, `base`, `null`, `sizeof`, `typeof`, and possibly a few others.
Joe White
Hell, you could initialize a default parameter to an anonymous delegate or a lambda: `(..., Action action = () => { /* go to town */ })`. Technically it's still part of the method declaration, but now you can write *any statement* -- so `return`, `switch`, `checked`/`unchecked`, `fixed`, and a whole bunch else become fair game.
Joe White
@Joe: Brilliant. You could even put a lambda, couldn't you? Then you could squeeze in a `return` as well
jalf
would the nullable types count as a keyword itself?
Yves M.
@Joe White: I think you just blew the interviewers mind. Anybody answering with that get's the job on the spot..
Jimmy Hoffa
Oh, and don't forget to use LINQ in the default parameters. Not sure on this one though; most of LINQ isn't technically keywords, since they're not reserved (you can declare your own variable called `from`). But still.
Joe White
I think that interviewer needs to specify 3.5 next time! Those defaults make it a bit rediculous.
Grant Crofton
You can't use `as` in a default. (It must be a compile-time constant)
SLaks
@Joe: You can't use LINQ or lambdas in a default either.
SLaks
Now, the only question is can someone think of a suitable, self commenting, method name...
Martin Harris
`Default parameter value for 'pointless' must be a compile-time constant`
SLaks
+78  A: 

This declaration uses 38 keywords:

[method: MethodImpl(MethodImplOptions.InternalCall)]
[SomeAttribute(typeof(object))]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern unsafe void MyMethod<T1, T2, T3>(
    this sbyte a, ref short b, out int c, long d, 
    byte e, ushort f, uint g, [parameter: MarshalAs(UnmanagedType.U4)]ulong h,
    float i, char j = default(char), bool k = false, global::System.Boolean l = true,
    double m = sizeof(int), decimal? n = null, dynamic o = null, params string[] z)
where T1 : struct where T2 : class where T3 : new();

It actually compiles, too.

SLaks
you miss the generics...
Yves M.
till now you're the bhest - 24 keywords ! :)
Andrzej Nosal
When you use override you cannot use contraints, my compiler tells me.
Jens
You're the man, but as someone mentioned above, one of the parameters should be `= default(T)`. Oh, hmm, my compiler complains that you can't set a default value for a `params` array : (
mquander
@Yves: indeed, one of the argument types could be something like `MyGeneric<in T, out S>` for an extra one or two keywords (are different uses of `out` different keywords?)
Richard
@mquander: Yes; I just fixed that.
SLaks
You could probably get a `global` in there. `global::System.Double`
Mark H
Surely the attributes don't count as keywords though?
Grant Crofton
@Richard: No, you can't. Those can only be used in interfaces.
SLaks
@Grant - the attribute itself doesn't, but it's required for the `internal` to work. However, you could turn the attribute to say `[method:MethodImpl(...)]`, though I'm not sure if `method` is a keyword, it's highlighted as such in VS.
Mark H
Can you fit delegate or event in as parameters or constraints? Or maybe even as accessors?
Jimmy Hoffa
Could you add `T4 : enum` or I'm wrong
Andrzej Nosal
@A: [No, you can't](http://stackoverflow.com/questions/1331739/enum-type-constraints-in-c/1416660#1416660).
SLaks
@Mark: You mean extern. Thanks; I'd forgotten about those.
SLaks
You can have `dynamic` args, can you not?
Mark H
@Mark: Yes; thanks.
SLaks
Really like the use of attributes to sneak in some extra keywords, but I would question whether they are strictly part of a "method declaration" rather than metadata. Though I think we both left the spirit of the question behind long ago.
Martin Harris
@Martin: If Grant's thoughts on the question are correct, using attributes in this manner does not necessarily avoid the spirit of the question.
Brian
@SLaks: I added the `protected` keyword...still compiles.
Brian Gideon
@Brian Gideon Are you sure? The first parameter is a 'this' which marks it as an extension method. You can't have protected methods in a static class (which it'll needs to be to declare extensions)
Martin Harris
@Martin: Doh...you're right. I didn't see that. I reverted my edit. That's pretty funny actually. The signature is so complicated now that you cannot see the trees through the forest :)
Brian Gideon
I'm weeping....and I don't know why
curtisk
A truly beautiful piece of code, easy to read and maintain.
Daniel Daranas
You can learn half of c# syntax reading this declaration (-:
Oren A
There are many words I would use to describe this code, but "reasonable" is not one of them.
Ken
I would ask the interviewer to define reasonable.
abhi
The keywords get, set, value, add, remove, assembly, module, type, method, field, property, param, typevar, where, partial, global, yield, alias, hidden, default, disable, restore, checksum, from, join, on, equals, into, orderby, ascending, descending, group, by, select, let, var and dynamic are all *unreserved contextual keywords*. You can use them as type or parameter names in a declaration. Feel free to use any of those that you haven't already!
Eric Lippert
@Eric: They don't count. (Unless used in context, such as `default`, `dynamic`, `method`, `parameter`, and `return`)
SLaks
How are `checksum`, `disable`, and `restore` keywords? For `#pragma`?
SLaks
Also, do you mean `params`?
SLaks
The question uses a key word too, which was **reasonable** :).
Daniel Cassidy
@SLaks: checksum, disable and restore are not actually defined by the language but they are recognized by the compiler for the #pragma directive. "param" is an attribute target.
Eric Lippert
@Eric: **Why** does this parameter compile: `[garbage: MarshalAs(UnmanagedType.U4)]ulong h,`?
SLaks
@SLaks: When I compile that I get "warning: garbage is not a recognized attribute location. All attributes in this block will be ignored". Is your question why this is a warning rather than an error?
Eric Lippert
@Eric: Yes. I was testing in LINQPad, so I didn't see the warning.
SLaks
@SLaks: I see no justification for why this is a warning and not an error, either in the spec, the design notes, or the code. It certainly looks like it ought to be an error. The only thing I can think of is maybe it's for some forwards compatibility situation. I'll ask one of the old timers if they remember why they did this strange thing.
Eric Lippert
They don't remember, but concur that it was probably for some forwards-compat scenario.
Eric Lippert
Now give us a real world example where this method would be useful/necessary ("Answering a stupid interview question" doesn't count).
DrDro
@DrDro, It unnecessarily has to be applied somwhere (though it cannot be excluded). It can be used as quick reference when you forget syntax of generic constrained extension method or to show beginner, in one example how to define method. It can be also a thought excercise which reminds you that `partial` and `extern` cannot be mixed :)
Andrzej Nosal
+8  A: 

I quite like it, it shows knowledge of access modifiers, variable passing, types, generics and so on, it's probably going to make the interviewee think a bit, and it's unlikely somthing they'll have learned off the Internet just to pass the interview.

Grant Crofton
"unlikely something they'll have learned off the Internet"...Until now. =;)
Simon P Stevens
Damn you SO users and your answers!
Grant Crofton
A: 

I think an interesting approach would be to write a program that from a list of keywords and rules, constructs the longest possible function declaration. This would demonstrate even more skill on the interviewee's part and if done correctly provide without doubt the best solution.

Ben
@Ben: I think Eric Lippert's "Every Program There Is" series ( see http://blogs.msdn.com/b/ericlippert/archive/tags/grammars/ ) is quite relevant to this approach.
Brian
+2  A: 

I think the kind of discussion we can see in the top answers' comments is what the interviewer was looking for. As often, the interviewer was less interested in the final answer then in the process. Explaining why you couldn't use this keyword in your current declaration and how you can use that one shows that you understand (some of) the main concepts.

DrDro