C# and variable number of parameters - c#

I tried the following code:
class Program: ProgParent
{
public int Max(params int[] op)
{
return 0;
}
public int Max(int i, params int[] op)
{
return 1;
}
public int Max(int i, int j, params int[] op)
{
return 2;
}
public static void Main(string[] args)
{
System.Console.WriteLine((new Program()).Max(5, 6, 7, 8));
System.Console.ReadKey();
}
}
It executes, and uses the most specific function available. But the compiler gives no warning or error about this. Why?

The C# language spec says:
When performing overload resolution, a method with a parameter array
may be applicable either in its normal form [i.e. passing an array] or
its expanded form [i.e. passing a variable number of parameters]. The
expanded form of a method is available only if the normal form of the
method is not available and only if a method with the same signature
as the expanded form is not already declared in the same type"
In a (slightly simplified) nutshell: If overload resolution is ambiguous, the compiler chooses the non-params overload.
I guess the reasons for that decision (instead of making code like yours illegal) include:
If your method has the signature: void fn(params object[] p), you want to have some way to call the "normal form" (by passing an object[]). So the compiler has to handle ambiguous cases anyway.
Creating a temporary array is a lot more expensive than a method call, so you might want to create non-params overloads with 1,2,3 parameters that behave the same but are more efficient. (like e.g. String.Format)

Ignoring the build errors (which I'm putting down to typos) - what warning would you expect or want? It is finding a matching overload and using it...
Strictly speaking, I can call different overloads - by passing arrays, but yes, the usage isn't entirely clear.
Without the multiple overloads with params, this pattern is used quite heavily in things like string.Concat etc (which underpins + for strings under the bonnet).

Related

How to use existing method instead of lambda when it's not static?

This must be a duplicate but i haven't found it. I've found this question which is related since it answers why it's recommended to use a method group instead of a lambda.
But how do i use an existing method group instead of a lambda if the method is not in the current class and the method is not static?
Say i have a list of ints which i want to convert to strings, i can use List.ConvertAll, but i need to pass a Converter<int, string> to it:
List<int> ints = new List<int> { 1 };
List<string> strings = ints.ConvertAll<string>(i => i.ToString());
This works, but it creates an unnecessary anonymous method with the lambda. So if Int32.ToString would be static and would take an int i could write:
List<string> strings = ints.ConvertAll<string>(Int32.ToString);
But that doesn't compile - of course. So how can i use a method group anyway?
If i'd create an instance method like this
string FooInt(int foo)
{
return foo.ToString();
}
i could use strings = ints.ConvertAll<string>(FooInt);, but that is not what i want. I don't want to create a new method just to be able to use an existing.
There is an static method in the framework, that can be used to convert any integrated data type into a string, namely Convert.ToString:
List<int> ints = new List<int> { 1 };
List<string> strings = ints.ConvertAll<string>(Convert.ToString);
Since the signature of Convert.ToString is also known, you can even eliminate the explicit target type parameter:
var strings = ints.ConvertAll(Convert.ToString);
This works. However, I'd also prefer the lambda-expression, even if ReSharper tells you something different. ReSharper sometimes optimizes too much imho. It prevents developers from thinking about their code, especially in the aspect of readability.
Update
Based on Tim's comment, I will try to explain the difference between lambda and static method group calls in this particular case. Therefor, I first took a look into the mscorlib disassembly to figure out, how int-to-string conversion exactly works. The Int32.ToString method calls an external method within the Number-class of the System namespace:
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), SecuritySafeCritical]
public string ToString(IFormatProvider provider)
{
return Number.FormatInt32(this, null, NumberFormatInfo.GetInstance(provider));
}
The static Convert.ToString member does nothing else than calling ToString on the parameter:
[__DynamicallyInvokable]
public static string ToString(int value)
{
return value.ToString(CultureInfo.CurrentCulture);
}
Technically there would be no difference, if you'd write your own static member or extension, like you did in your question. So what's the difference between those two lines?
ints.ConvertAll<string>(i => i.ToString());
ints.ConvertAll(Convert.ToString);
Also - technically - there is no difference. The first example create's an anonymous method, that returns a string and accepts an integer. Using the integer's instance, it calls it's member ToString. The second one does the same, with the exception that the method is not anonymous, but an integrated member of the framework.
The only difference is that the second line is shorter and saves the compiler a few operations.
But why can't you call the non-static ToString directly?
Let's take a look into the ConvertAll-method of List:
public List<TOutput> ConvertAll<TOutput>(Converter<T, TOutput> converter)
{
if (converter == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.converter);
}
List<TOutput> list = new List<TOutput>(this._size);
for (int i = 0; i < this._size; i++)
{
list._items[i] = converter(this._items[i]);
}
list._size = this._size;
return list;
}
The list iteraterates over each item, calls the converter with the item as an argument and copys the result into a new list which it returns in the end.
So the only relation here is your converter that get's called explicitly. If you could pass Int32.ToString to the method, the compiler would have to decide to call this._items[i].ToString() within the loop. In this specific case it would work, but that's "too much intelligence" for the compiler. The type system does not support such code conversions. Instead the converter is an object, describing a method that can be called from the scope of the callee. Either this is an existing static method, like Convert.ToString, or an anonymous expression, like your lambda.
What causes the differences in your benchmark results?
That's hard to guess. I can imagine two factors:
Evaluating lambdas may result in runtime-overhead.
Framework calls may be optimized.
The last point especially means, that the JITer is able to inline the call which results in a better performance. However, those are just assumptions of mine. If anyone could clarify this, I'd appreciate it! :)
You hit the nail on the head yourself:
This works, but it creates an unnecessary anonymous method with the
lambda.
You can't do what you're asking for because there is no appropriate method group that you can use so the anonymous method is necessary. It works in that other case because the implicit range variable is passed to the delegate created by the method group. In your case, you need the method to be called on the range variable. It's a completely different scenario.

Using object type as a parameter

I've been wondering about this: would you support using simply an object as a parameter in your method? My reason behind doing this would be overloading. Currently, I'm trying to create a method that caters to many different datatypes: string, decimal, DateTime... the list goes on.
It's getting a bit messy though, so I was thinking of doing the following
public void GenericMethod(object val)
{
if (val is string)
// process as string
else if (val is decimal)
// process as decimal
else if (val is DateTime)
// do something for dt
else
// ...
}
What do you think of such a method? Would it incur unnecessary overhead? (during type checking) Have you implemented it? Tell me...
EDIT: Yeah, and just a sidenote, I'm kinda familiar with overloading. But it gets a little annoying when there are like more than 10 overloads...
Yes, that would work. However there are better ways of doing this.
Your best bet is to use overloads:
public void GenericMethod(string val)
{
// process as string
}
public void GenericMethod(decimal val)
{
// process as decimal
}
etc.
Whenever you use a is keyword in your code that's a huge hint that you're probably forgetting to use some important O.O. principles: overloads, subclasses, or the like.
Overloads aren't actually that annoying to work with, just to write. Remember, you're not coding this for yourself today, you're coding this for yourself three months from now when you have to read the code and figure out why the heck you did it that way, or where in the world that bug comes from.
Yet another reason to avoid the "switch on type" technique is for consistency with the .NET framework (and thus people's expectations). Follow Console.Write and the other wide variety of methods that are overridden within and under a given class.
I've been wondering about this: would you support using simply an object as a parameter in your method?
Very rarely. If there's a fixed set of types which are properly supported - and you'll throw an exception otherwise - then I'd use overloads.
If you can actually accept any type, and you'll handle a not-specially-supported type in some well-known way, then it's okay to accept object. That's what LINQ to XML does all over the place, and the result is a very clean API. I'd do it very carefully though - it's rarely a good idea.
And yes, there'd be an overhead. I wouldn't usually make that the basis of the decision though - the overhead will be small enough to be negligible in most cases. Design your API as cleanly as you can, then work out whether it's going to cause a bottleneck.
Yes, it would incur overhead for both type checking and boxing/unboxing the value type. I would recommend the overloads.
Another possibility, as long as you aren't doing a lot of math with the number, would be to make it a generic method. Arithmetic is rather difficult with generics though, as there are no constraints for value types which enables the use of operators.
No need of those!
Just declare as many methods with same name as you want and take each type as argument in each method.[This is called Overloading. e.g. You may have seen that +1 Overloads beside Methods, which implies that there is 1 more Method with same name but with different argument types]
Say Like this :
void Method(decimal d)
{
//Process Decimal
}
void Method(string s)
{
//Process String
}
By default, It will find its own method according to the Type.
There are cases where your approach makes sense. I've used it before, mostly when I have a bunch of processing that is the same for different data types.
But this is not overloading. Overloading would be to define different signatures for the same method name like this:
public void GenericMethod(string val)
{
// process as string
}
public void GenericMethod(decimal val)
{
// process as decimal
}
public void GenericMethod(DateTime val)
{
// do something for dt
}
// Etc.
And for some cases, this approach makes more sense.
Implementing many overloads one of them takes object is no problem. Take a look at Console.WriteLine overloads for example. http://msdn.microsoft.com/en-us/library/system.console.writeline.aspx However, take care that int for example can conflict with double:
int sum(int i, int j)
{
return i + j;
}
double sum(double i, double j)
{
return i + j;
}
object sum(object i, object j)
{
return i.ToString() + j.ToString();
}
==============================
static void Main()
{
sum(1, 2); // Error: ambigous call between `int` and `double` versions
sum(1.0, 2.0); // calls double version, although 1.0 and 2.0 are objects too
sum("Hello", "World"); // object
}

Creating two delegate instances to the same anonymous method are not equal

Consider the following example code:
static void Main(string[] args)
{
bool same = CreateDelegate(1) == CreateDelegate(1);
}
private static Action CreateDelegate(int x)
{
return delegate { int z = x; };
}
You would imagine that the two delegate instances would compare to be equal, just as they would when using the good old named method approach (new Action(MyMethod)). They do not compare to be equal because the .NET Framework provides a hidden closure instance per delegate instance. Since those two delegate instances each have their Target properties set to their individual hidden instance, they do not compare. One possible solution is for the generated IL for an anonymous method to store the current instance (this pointer) in the target of the delegate. This will allow the delegates to compare correctly, and also helps from a debugger standpoint since you will see your class being the target, instead of a hidden class.
You can read more about this issue in the bug I submitted to Microsoft. The bug report also gives an example of why we are using this functionality, and why we feel it should be changed. If you feel this to be an issue as well, please help support it by providing rating and validation.
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=489518
Can you see any possible reason why the functionality should not be changed? Do you feel this was the best course of action to get the issue resolved, or do you recommend that I should take a different route?
I'm not so inclined to think this is a "bug". It appears moreover that you're assuming some behaviour in the CLR that simply does not exist.
The important thing to understand here is that you are returning a new anonymous method (and initialising a new closure class) each time you call the CreateDelegate method. It seems that you are experting the delegate keyword to use some sort of pool for anonymous methods internally. The CLR certainly does not do this. A delegate to the anonymous method (as with a lambda expression) is created in memory each time you call the method, and since the equality operator does of course compare references in this situation, it is the expected result to return false.
Although your suggested behaviour may have some benefits in certain contexts, it would probably be quite complicated to implement, and would more likely lead to unpredictable scenarios. I think the current behaviour of generating a new anonymous method and delegate on each call is the right one, and I suspect this is the feedback you will get on Microsoft Connect as well.
If you are quite insistent on having the behaviour you described in your question, there is always the option of memoizing your CreateDelegate function, which would insure that the same delegate is returned each time for the same parameters. Indeed, because this is so easy to implement, it is probably one of the several reasons why Microsoft did not consider implementing it in the CLR.
EDIT: Old answer left for historical value below the line...
The CLR would have to work out the cases in which the hidden classes could be considered equal, taking into account anything that could be done with the captured variables.
In this particular case, the captured variable (x) isn't changed either within the delegate or in the capturing context - but I'd rather the language didn't require this sort of complexity of analysis. The more complicated the language is, the harder it is to understand. It would have to distinguish between this case and the one below, where the captured variable's value is changed on each invocation - there, it makes a great deal of difference which delegate you call; they are in no way equal.
I think it's entirely sensible that this already-complex situation (closures are frequently misunderstood) doesn't try to be too "clever" and work out potential equality.
IMO, you should definitely take a different route. These are conceptually independent instances of Action. Faking it by coercing the delegate targets is a horrible hack IMO.
The problem is that you're capturing the value of x in a generated class. The two x variables are independent, so they're unequal delegates. Here's an example demonstrating the independence:
using System;
class Test
{
static void Main(string[] args)
{
Action first = CreateDelegate(1);
Action second = CreateDelegate(1);
first();
first();
first();
first();
second();
second();
}
private static Action CreateDelegate(int x)
{
return delegate
{
Console.WriteLine(x);
x++;
};
}
}
Output:
1
2
3
4
1
2
EDIT: To look at it another way, your original program was the equivalent of:
using System;
class Test
{
static void Main(string[] args)
{
bool same = CreateDelegate(1) == CreateDelegate(1);
}
private static Action CreateDelegate(int x)
{
return new NestedClass(x).ActionMethod;
}
private class Nested
{
private int x;
internal Nested(int x)
{
this.x = x;
}
internal ActionMethod()
{
int z = x;
}
}
}
As you can tell, two separate instances of Nested will be created, and they will be the targets for the two delegates. They are unequal, so the delegates are unequal too.
I don't know about the C# specific details of this problem but I worked on the VB.Net equivalent feature which has the same behavior.
The bottom line is this behavior is "By Design" for the following reasons
The first is that in this scenario a closure is unavoidable. You have used a piece of local data within an anonymous method and hence a closure is necessary to capture the state. Every call to this method must create a new closure for a number of reasons. Therefore each delegate will point to an instance method on that closure.
Under the hood a anonymous method / expression is represented by a System.MulticastDelegate derived instance in code. If you look at the Equals method of this class you will notice 2 important details
It is sealed so there is no way for a derived delegate to change the equals behavior
Part of the Equals method does a reference comparison on the objects
This makes it impossible for 2 lambda expressions which are attached to different closures to compare as equals.
I can't think of a situation where I've ever needed to do that. If I need to compare delegates I always use named delegates, otherwise something like this would be possible:
MyObject.MyEvent += delegate { return x + y; };
MyObject.MyEvent -= delegate { return x + y; };
This example isn't great for demonstrating the issue, but I would imagine that there could be a situation where allowing this could break existing code that was designed with the expectation that this is not allowed.
I'm sure there are internal implementation details that also make this a bad idea, but I don't know exactly how anonymous methods are implemented internally.
This behaviour makes sense because otherwise anonymous methods would get mixed up (if they had the same name, given the same body).
You could change your code to this:
static void Main(){
bool same = CreateDelegate(1) == CreateDelegate(1);
}
static Action<int> action = (x) => { int z = x; };
private static Action<int> CreateDelegate(int x){
return action;
}
Or, preferably, since that's a bad way to use it (plus you were comparing the result, and Action doesn't have a return value ... use Func<...> if you want to return a value):
static void Main(){
var action1 = action;
var action2 = action;
bool same = action1 == action2; // TRUE, of course
}
static Action<int> action = (x) => { int z = x; };

C# variable length args, which is better and why: __arglist, params array or Dictionary<T,K>?

I recently read the following overflow post:
Hidden Features of C#
One of the features pointed out was the arglist. Why would one choose this or the alternatives as a means of using a variable length argument list to a method? Also, note that I would probably not use this kind of construct in my code unless a corner case warranted doing so. This is more of a question of semantics than whether it is even practical or prudent to even use variable length arguments. So does anyone know which is better and why?
[Test]
public void CanHandleVariableLengthArgs()
{
TakeVariableLengthArgs(__arglist(new StringBuilder(), 12));
object[] arr = { new StringBuilder() };
TakeVariableLengthArgs2(arr);
TakeVariableLengthArgs3(
new Dictionary<string, object>
{ { "key", new StringBuilder() } });
}
public void TakeVariableLengthArgs(__arglist)
{
var args = new ArgIterator(__arglist);
var a = (StringBuilder)TypedReference.ToObject(args.GetNextArg());
a.Append(1);
}
public void TakeVariableLengthArgs2(params object[] args)
{
var a = (StringBuilder)args[0];
a.Append(1);
}
public void TakeVariableLengthArgs3(Dictionary<string, object> args)
{
var a = (StringBuilder)args["StringBuilder"];
a.Append(1);
}
I would certainly never use __arglist, since it's undocumented and nobody knows what it means in any case.
I'd also avoid variable-length argument lists for as long as possible, and instead rework my design to understand what is truly variable, and to model that variability in a less platform-dependant manner.
It depends on the case. I've used params in cases where I have a variable number of arguments and it significantly adds to the readability of the calling code.
For example, I have a class that represents a TIFF document and allows access to a collection of pages which can be reordered and interspersed with other TIFF documents. Since one of the most common tasks our customers want is the ability to easily combine multiple TIFF documents into a single, we also provide the following two utility methods:
public static void Combine(Stream output, params Stream[] sources) { /* ... */ }
public static void Combine(Stream output, params string[] sourceFiles) { /* ... */ }
which in usage make the client code feel really nice:
using (FileStream output = new FileStream(outputPath, FileMode.Create)) {
TiffDocument.Combine(output, tpsCoverSheetPath, mainDocumentPath, tpsTrailerPath);
}
In general, you are probably better off avoiding undocumented features of the language - for several reasons.
They are more likely to change then the established, documented features
They may have side-effects and implications that are not obvious in their usage
Other developers will not be familiar with them and will have a harder time maintaining your code
Refactoring tools (like VS itself or Resharper) are unlikely to be able to recognize them
They take away clarity from the intent of your code
There are language-supported alternatives to most of them
In the specific case of the __arglist, you can achieve the same capabilities with the language supported params keyword, which allows you to create type-safe variable argument lists for methods in C#. As a practice, though, I would be careful using it as it can obfuscate your code if used inpropertly - good use cases (like those in string.Format() which accepts variable arguments) - are less frequent than you would think.
C# 4 will have a better mechanism for this; named and optional arguments:
static void Main(string[] args)
{
// The method can be called in the normal way, by using positional arguments.
Console.WriteLine(CalculateBMI(123, 64));
// Named arguments can be supplied for the parameters in either order.
Console.WriteLine(CalculateBMI(weight: 123, height: 64));
Console.WriteLine(CalculateBMI(height: 64, weight: 123));
// Positional arguments cannot follow named arguments.
// The following statement causes a compiler error.
//Console.WriteLine(CalculateBMI(weight: 123, 64));
// Named arguments can follow positional arguments.
Console.WriteLine(CalculateBMI(123, height: 64));
}
static int CalculateBMI(int weight, int height)
{
return (weight * 703) / (height * height);
}
I would prefer to not use any of the three techniques described here. I would instead design a value object that has strong types wherever possible, and possibly even nullable types. If push comes to shove you can create a generics-typed value object too.
There's just all so much code smell in this way of coding for me. A variable length collection of object ? Wouldn't pass unnoticed in my code review.
Edit:
And if it DID pass my code review the parameter would in all likelyhood be an IEnumerable instance and none of the three suggestions items. IEnumerable is the leanest thing that could encapsulate my needs.

Extension methods defined on value types cannot be used to create delegates - Why not?

Extension methods can be assigned to delegates that match their usage on an object, like this:
static class FunnyExtension {
public static string Double(this string str) { return str + str; }
public static int Double(this int num) { return num + num; }
}
Func<string> aaMaker = "a".Double;
Func<string, string> doubler = FunnyExtension.Double;
Console.WriteLine(aaMaker()); //Prints "aa"
Console.WriteLine(doubler("b")); //Prints "bb"
If the type they're extending is a value type, it won't work:
Func<int> eightMaker = 4.Double; //Error CS1113: Extension methods 'FunnyExtension.Double(int)' defined on value type 'int' cannot be used to create delegates
Func<int, int> intDoubler = FunnyExtension.Double; //Works
This gives
Error CS1113: Extension methods 'FunnyExtension.Double(int)' defined
on value type 'int' cannot be used to create delegates.
Why can't they?
In response to my other answer, Eric Smith correctly notes:
"... because it would require implicitly boxing the receiver type parameter ...". Which is what happens anyway, if you do something like this: Func f = 5.ToString; Which is perfectly legal.
Thinking about this has led me to a new answer. Try this on for size:
Ordinary "instance" methods on structs take, at the CIL level, a "managed pointer" (type &) as a receiver parameter. This is necessary so that instance methods on structs can assign to fields of the struct. See Partition II, Section 13.3.
Similarly, instance methods on classes take an "object reference" (type O) as a receiver parameter (the difference being that this is a pointer to the managed heap, and needs to be tracked for GC).
Since both CIL &s and Os can be (and are) implemented by pointers, everything is hunky-dory for the delegate implementation. Regardless of whether a delegate captures a static method, a class instance method, or a struct instance method, all it needs to do is pass the pointer to its _target to the first argument of the function.
But the scenario we are discussing ruins that. A static extension method taking an int as a first argument requires a CIL argument of type int32 (see Partition III, section 1.1.1). Here is where things go off the rails. I don't see any reason why it wouldn't be possible for the implementation of delegates to realize that this was happening (for example, by inspecting the metadata associated with the MethodInfo being captured) and emit a thunk that would unbox the _target and pass that as the first argument, but this isn't needed for delegates to classical instance methods on structs, since they expect a pointer anyway and doesn't appear (judging by the example in my earlier incorrect answer) to be implemented. Obviously the specific value type in question would control the exact nature of the required thunk.
Unless I am missing a more fundamental obstacle to implementation (I could imagine that it would pose problems for the verifier, for example), it seems like a reasonable case could be made for extending the runtime to support this case, but all the signs are pointing towards this being a limitation of the runtime and not of the C# compiler per se.
EDIT 2
I don't believe this answer anymore, but I left it here so the thread would still make sense and so that people would see why it isn't right. See my other answer for a different take on the matter.
Original
Because it would require implicitly boxing the value type receiver parameter (because the _target field in the System.Delegate type which holds the the receiver parameter is of type System.Object), which could lead to some strange aliasing behavior if you weren't expecting it.
EDIT
There is something else going on here. I ran this sample program:
class Program
{
public static int Combine(int a, int b)
{
return a + b;
}
static void Main(string[] args)
{
var combineMethod = typeof(Program).GetMethod("Combine");
var add4 = Delegate.CreateDelegate(
typeof(Converter<int, int>),
4,
combineMethod) as Converter<int, int>;
for (int i = 0; i < 10; i++)
{
Console.WriteLine(add4(i));
}
Console.ReadLine();
}
}
and got an ArgumentException: "Error binding to target method." at the call to CreateDelegate. I'm not sure why, and because the relevant method is an internalcall method, Reflector isn't much help. The documentation for CreateDelegate also wasn't much help. I'm sure it has something to do with boxing the receiver, maybe someone with knowledge of the Rotor source could help explain why?

Categories