Is there a C# alternative to Java's vararg parameters? - c#

I have worked on Java and new to .Net technology
Is it possible to declare a function in C# which accepts variable input parameters
Is there any C# syntax similar to the following Java syntax?
void f1(String... a)

Yes, C# has an equivalent of varargs parameters. They're called parameter arrays, and introduced with the params modifier:
public void Foo(int x, params string[] values)
Then call it with:
Foo(10, "hello", "there");
Just as with Java, it's only the last parameter which can vary like this. Note that (as with Java) a parameter of params object[] objects can easily cause confusion, as you need to remember whether a single argument of type object[] is meant to be wrapped again or not. Likewise for any nullable type, you need to remember whether a single argument of null will be treated as an array reference or a single array element. (I think the compiler only creates the array if it has to, but I tend to write code which avoids me having to remember that.)

Have a look at params (C# Reference)
The params keyword lets you specify a method parameter that takes a
variable number of arguments.
You can send a comma-separated list of arguments of the type specified
in the parameter declaration, or an array of arguments of the
specified type. You also can send no arguments.
No additional parameters are permitted after the params keyword in a
method declaration, and only one params keyword is permitted in a
method declaration.
As shown in the example the method is declared as
public static void UseParams(params int[] list)
{
for (int i = 0; i < list.Length; i++)
{
Console.Write(list[i] + " ");
}
Console.WriteLine();
}
and used as
UseParams(1, 2, 3, 4);

Related

How to call named params parameter? Edit: Overloading Suggestion;

An overloaded method sample, for named parameter call:
internal static dynamic TestMethod(int P1a, int P1b, params dynamic[] P1c)
{
//Sample Code
}
[Overload: P2] //illustration : Overload Specification
internal static dynamic TestMethod(int P2a, int P2b, params dynamic[] P2c)
{
//Sample Code
}
Having a new set of code organization, is to specify which overload to use
using named parameters would resolve the problem or declare the method for overload selection;
TestMethod(P2: 1, 1,2,3,4,5);
They two features are not compatible. You would have to construct the array yourself, rather than having the compiler do that for you (an array is always constructed either way).
How do we know they're not compatible? From Argument lists:
An argument with an argument_name is referred to as a named argument, whereas an argument without an argument_name is a positional argument. It is an error for a positional argument to appear after a named argument in an argument_list.
Note that last sentence - you cannot have positional arguments after a named argument.
Runtime evaluation of argument lists:
Methods, indexers, and instance constructors may declare their right-most parameter to be a parameter array
...
When a function member with a parameter array is invoked in its expanded form, the invocation must specify zero or more positional arguments for the parameter array ...
(My emphasis)
That is, the params feature only works with positional arguments.

Passing a generic pointer to a method in c#

I have created a generic type to act as a pointer so that I can pass by reference. (Perhaps there is a much more simple way of doing this but I want to stress that I am doing this to learn more about generics and passing by reference, not the most efficient way of completing the task, if that makes sense.)
Here is the code I wrote for the generic type
class GenericPointer<T> {
public T item;
public void setItem(T i){ item = i; }
public T getItem(){ return item; }
}
In my program I have created an instance of this type called 'intPointer'. The value 143 is arbitrary.
GenericPointer<int> intPointer = new GenericPointer<int>();
intPointer.setItem(143);
Console.WriteLine(intPointer.getItem());
The above code runs properly, setting and returning the value 143.
I now want to pass this 'intPointer' to a method that increments it and then prints the value again.
So I wrote a method called addone()
public void addone(int i) { i ++; }
Now I want to make the following calls (remembering that I already set the value to 143):
Console.WriteLine(intPointer.getItem());
addone(intPointer);
Console.WriteLine(intPointer.getItem());
What I was expecting to see was 143 then 144 however I get the following errors:
The best overloaded method match for 'Notes.Program.addone(int)' has some invalid arguments
and:
cannot convert from 'Notes.GenericPointer<int>' to 'int'
Any help would be greatly appreciated!
I'll begin by correcting some of your terminology: you're not using pointers. C# does support pointers, but using the unsafe keyword, and they are real pointers (as in, integer memory addresses you can directly manipulate). The code you written is just an example of a boxed object.
.NET supports boxing already, by casting to Object; however it isn't recommended nor needed because the ref keyword solves the problem you're trying to "fix".
Use the ref keyword to describe a value-type parameter that should be passed by-reference instead of by-value. All other semantics remain the same, like so:
void Foo() {
int x = 123;
Bar(ref x);
Console.Write( x ); // prints "124".
}
void Bar(ref int x) {
x++;
}
I have a few other notes:
C# and .NET conventions dictate that all public members (methods, properties, fields, etc) should have TitleCase, not camelCase (i.e. ensure the first letter is capitalised).
Trivial getter and setter methods are discouraged, used Properties instead (though I note you cannot use ref arguments with properties).
You're getting your error because the type of intPointer is not int, but your class GenericPointer<int>.
While GenericPointer is wrapping an int, it is not actually an int so it cannot be treated as one. It has properties that are an int.
Imagine if GenericPointer wrapped a string. What would AddOne do to that.
You can act on the properties of the class but not treat the entire class as its generic type.
It would be possible to write an AddOne method that took a Generic Pointer argument and then inspected it for intyness and then added one to the internal item if it was an int. I am sure that is not a good idea.
What are you really trying to achieve with this GenericPointer?
If you want parameters to be reference if they are a value type (string, int, bool, etc.) then make your parameter like this:
public void addone(ref int i)
{
i++;
}
Then call the method like so:
addone(ref variableInt);
You can also look at this in order to see how to make your classes work as a specific type.

What is the difference between Func<string,string> and delegate?

I see delegates in two forms:
A. Func<string, string> convertMethod = lambda
B. public delegate string convertMethod(string value);
I'm uncertain of what actually the difference between these two are. Are they both delegates? I believe the first one would use a lambda and the second would have to have a method to actually perform the work. I may be confused too.
First of all, your two examples are doing two totally separate things. The first is declaring a generic delegate variable and assigning a value to it, the second is just defining a delegate type. Your example, more completely, would be:
public static class Program
{
// you can define your own delegate for a nice meaningful name, but the
// generic delegates (Func, Action, Predicate) are all defined already
public delegate string ConvertedMethod(string value);
public static void Main()
{
// both work fine for taking methods, lambdas, etc.
Func<string, string> convertedMethod = s => s + ", Hello!";
ConvertedMethod convertedMethod2 = s => s + ", Hello!";
}
}
But more to the point, both Func<string,string> and delegate string convertMethod(string) would be capable of holding the same method definitions whether they be methods, anonymous methods, or lambda expressions.
As for which you should use, depends on the situation. If you want your delegate to be defined more by what it takes and returns, then the generic delegates are perfect. If you want the delegate to have some special name that gives more definition of what that delegate should do (beyond simple Action, Predicate, etc) then creating your own delegate is always an option.
The code sample you have is confusing things a bit so let me try and clear it up. The following 2 items are delegate declarations. These are easy to spot because they will always contain the delegate keyword
public delegate TReturn Func<TArg, TReturn>(Targ value);
public delegate string convertMethod(string value);
This line of code is assigning a value to a local which is typed to a delegate
Func<string, string> local = lambda;
The above code is not limited to using just lambdas though. The value could also be a compatible method group or another delegate value.
One other item to note is that even though Func<string, string> and convertMethod are both delegates with identical signatures their values are not convertible to each other. For example the following is illegal
Func<string, string> local1 = ...;
convertMethod local2 = local1; // Error!!!
From MSDN,
In versions of C# before 2.0, the only way to declare a delegate was
to use named methods. C# 2.0 introduced anonymous methods and in C#
3.0 and later, lambda expressions supersede anonymous methods as the
preferred way to write inline code.
and
There is one case in which an anonymous method provides functionality
not found in lambda expressions. Anonymous methods enable you to omit
the parameter list. This means that an anonymous method can be
converted to delegates with a variety of signatures.
You may also be interested in this SO answer on delegate keyword vs lambda expression.
Additionally, MSDN has a good article on Lambda Expressions:
delegate int del(int i);
static void Main(string[] args)
{
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
}
In the previous example, notice that the delegate signature has one
implicitly-typed input parameter of type int, and returns an int. The
lambda expression can be converted to a delegate of that type because
it also has one input parameter (x) and a return value that the
compiler can implicitly convert to type int. (Type inference is
discussed in more detail in the following sections.) When the delegate
is invoked by using an input parameter of 5, it returns a result of
25.
A initializes an instance of a delegate (that can be called immediately). It's a variable of type Func< string, string >.
B specifies the definition of a delegate (its signature). It can be used to later define variables of type convertMethod.

Why ref and out in C#?

While using keyword ref, calling code needs to initialize passed arguments, but with keyword out we need not do so.
Why don't we use out everywhere?
What is exact difference between the two?
Please give example of a situation in which we need to use ref and can't use out?
The answer is given in this MSDN article. From that post:
The two parameter passing modes
addressed by out and ref are subtly
different, however they are both very
common. The subtle difference between
these modes leads to some very common
programming errors. These include:
not assigning a value to an out
parameter in all control flow paths
not assigning a value to variable
which is used as a ref parameter
Because the C# language assigns
different definite assignment rules to
these different parameter passing
modes, these common coding errors are
caught by the compiler as being
incorrect C# code.
The crux of the decision to include
both ref and out parameter passing
modes was that allowing the compiler
to detect these common coding errors
was worth the additional complexity of
having both ref and out parameter
passing modes in the language.
out is a special form of ref where the referenced memory should not be initialized before the call.
In this case the C# compiler enforces that the out variable is assigned before the method returns and that the variable is not used before it has been assigned.
Two examples where out doesn't work but ref does:
void NoOp(out int value) // value must be assigned before method returns
{
}
void Increment(out int value) // value cannot be used before it has been assigned
{
value = value + 1;
}
None of these answers satisfied me, so here's my take on ref versus out.
My answer is a summary of the following two pages:
ref (C# Reference)
out (C# Reference)
Compare
Both the method definition and the calling method must explicitly use the ref / out keyword
Both keywords cause parameters to be passed by reference (even value types)
However, there is no boxing when a value type is passed by reference
Properties cannot be passed via out or ref, because properties are really methods
ref / out are not considered to be part of the method signature at compile time, thus methods cannot be overloaded if the only difference between them is that one of the methods takes a ref argument and the other takes an out argument
Contrast
ref
Must be initialized before it is passed
Can use to pass a value to the method
out
Does not have to be initialized before it is passed
Calling method is required to assign a value before the method returns
Can not use to pass a value to the method
Examples
Won't compile because only difference in method signatures is ref / out:
public void Add(out int i) { }
public void Add(ref int i) { }
Using ref keyword:
public void PrintNames(List<string> names)
{
int index = 0; // initialize first (#1)
foreach(string name in names)
{
IncrementIndex(ref index);
Console.WriteLine(index.ToString() + ". " + name);
}
}
public void IncrementIndex(ref int index)
{
index++; // initial value was passed in (#2)
}
Using out keyword:
public void PrintNames(List<string> names)
{
foreach(string name in names)
{
int index; // not initialized (#1)
GetIndex(out index);
Console.WriteLine(index.ToString() + ". " + name);
}
}
public void GetIndex(out int index)
{
index = IndexHelper.GetLatestIndex(); // needs to be assigned a value (#2 & #3)
}
Author's Random Remarks
In my opinion, the concept of using the out keyword is similar to using the Output enum value of ParameterDirection for declaring output parameters in ADO.NET
Arrays in C# are passed by reference, but in order for a reassignment of the array reference to affect the reference in the calling code, the ref keyword must be used
Example:
public void ReassignArray(ref int[] array)
{
array = new int[10]; // now the array in the calling code
// will point to this new object
}
For more info on reference types versus value types, see Passing Reference-Type Parameters (C# Programming Guide)
A contrived example of when you'd need to use ref and not out is as follows:
public void SquareThisNumber(ref int number)
{
number = number * number;
}
int number = 4;
SquareThisNumber(ref number);
Here we want number to be an in-out variable, so we use ref. If we had used out, the compiler would have given an error saying we initialized an out param before using it.
The ref keyword allows you to change the value of a parameter. The method being called can be an intermediate link in the calling chain. A method using the out keyword can only be used at the beginning of a calling chain.
Another advantage is that the existing value can be used in the logic of the method and still hold the return value.
In Oracle functions have explicit IN (default and what you get if you don't set a direction) IN/OUT and OUT parameters. The equivalent is normal (just the parameter), ref [parameter], and out [parameter].
The compiler knows that out variables shouldn't set before the call. This allows them be just declared before use. However it knows that it must be set before the function it's used in returns.
When we pass the value while calling the method prefixed by the out keyword, it treats it entirely different like we are not passing it to the method. Instead we are actually collecting (outing) the value of the out variable from the definition section of the method to the method out variable parameter where we are calling that method.
So out variable is the output of processing done with in the method definition, and this is the reason why we need to create it, initialize it, and modify it within the definition only.
An out variable is used when we need return multiple values from a particular method.
While in case of a ref variable we need to initialize it first as its memory location is transfered to method definition as parameter. Think what would happen if we are not initializing it before passing?

Optional parameters

I've got a method that takes a bunch of optional parameters and I'm overloading the method to supply the different combinations of signatures. Intellisense pops up with a bunch of different signatures but I think it looks quite confusing now because there are different combinations I need to provide, not just building up parameters on the end of the method signature.
Should I just not overload my method and stick to one signature so that the user of my method has to pass in nulls? It would make the signature clearer but makes the calling code look messier.
Are you restricted to using C# 1-3? C# 4 supports optional parameters and named arguments...
Until then, you should probably either stick with overloading or create a separate class with mutable properties, e.g.
FooOptions options = new FooOptions { Name="Jon", Location="Reading" };
Foo foo = new Foo(options);
That can all be done in one statement if you want... and if some of the properties are mandatory, then create a single constructor in FooOptions which takes all of them.
In C# 4 you'd be able to write:
Foo foo = new Foo(name: "Jon", location: "Reading");
if the constructor was written as
public Foo(string name,
int age = 0,
string location = null,
string profession = null)
Named arguments and optional parameters should make it a lot easier to construct immutable types with optional properties in C# 4 :)
Think about params argument of c# method.
void test(params object []arg) {
..
}
You could use the params keyword if the function definitions only vary in length (and not order, otherwise this wont be the best approach).Then in the function you can setup the values you need based on the parameter input

Categories

Resources