Validate Parameters at compile-time? - c#

Let's say I have a simple function:
public static int NewNumber(int lowestValue, int highiestValue) {}
I would like to have some a compiler check if parameters are correct. For example, in this case, the developer could mistakenly (or on purpose) call the method like this:
NewNumber(5, -5);
which is wrong in this case - The developer lied.
Sure I could make a simple check inside the method:
public static int NewNumber(int lowestValue, int highiestValue) {
if (highiestValue <= lowestValue) {
//Error
}
}
... and it would work just perfectly. However, I'm curious if there is anything the developer can do in this case to restrict such behavior without additional checking in the method itself.
EDIT: Found out the solution but nonrelated to the C#
Since I'm working in Unity I end up with writing custom inspector so values can be entered correctly in the Unity Inspector itself, thus eliminating unnecessary checks (and slowing the performance) when calling the method many times per second.

This I don't believe is possible. Consider this situation,
NewNumber(x, y);
What's x and y? The compiler doesn't necessarily know what the input is (e.g. x = Int32.Parse(Console.ReadLine());).
You gave hard-coded examples, and perhaps you might only use the function with hard-coded values, but the compiler only knows that 5 and -5 are integers and integers can be a literal 5, -5, etc or a variable var a = 5;

I don't think there is a compiler related parameter argument check. But it is always better to have your parameter check within your method (responsibility of your method to take care the parameter) and document it better so, the caller knows what data it should pass to your method.

Related

How to create a void method that outputs an integer and have the method divide the data passed to it by 2?

I'm really brand new at this and still learning C#. I've had a hard time trying to look for a good example to the assignment I'm working on.
So you can see exactly what I've been asked, here is the verbatim text of my assignment:
Perform these actions and create a console app that includes the
following:
Create a class. In that class, create a void method that outputs an integer. Have the method divide the data passed to it by 2.
In the Main() method, instantiate that class.
Have the user enter a number. Call the method on that number. Display the output to the screen. It should be the entered number, divided by two.
Create a method with output parameters.
Overload a method.
Declare a class to be static.
So far I created a class. In the Main() method, instantiate that class. I apologize in advance if the answer is on here. Point me to the direction if it is. Thank you.
in my main() program:
class Program
{
static void Main(string[] args)
{
MathMethod mathMethod = new MathMethod(); //Instantiate
}
}
my MathMethod.cs:
class MathMethod
{
public void Operator()
{
int num1 = 6;
int num2 = 9;
}
public void Output(int number1, int number2)
{
int value =
}
I'm not going to do your assignment but I'm happy to provide pointers for you to assemble into a solution for your assignment
The assignment text contains some confusing phrasing. I'd say "call the method on that number" should read "call the method, passing that number" - calling a method "on" is something different, and somewhat implies that you're expected to write an extension method (which I can't quite believe is a requirement for an assignment of this level)
It also asks things of you that I'm not sure I'd ask of a new learner but hey ho, we are where we are
For the most part I'd say that your particular problem here has been answered by Piotr; their answer adds rather than your requirement to divide but I'm sure you can work that one out. Also, their answer takes both operands to the operation but your assignment asks you to create a method that takes just one number, and halves it so your method won't have 3 parameters like Piotr's does, it will have 2
In the Main() method, instantiate that class.
This is done
Have the user enter a number.
Use a Console.WriteLine to prompt the user to do something, then use a Console.ReadLine to read their typing into a string variable
You'll also need to convert the string to an int; take a look at int.Parse which is easy to use.
You can look at upgrading to int.TryParse later, which is a more robust option that doesn't crash if the user enters garbage that can't be interpreted as a number. Amusingly/interestingly, TryParse works in the same way as what your assignment is asking you; it uses an out parameter to make the parsed number available. The reason why it uses an out is because it also returns a boolean indicating success or not so you can act accordingly; this is a more valid use case for out than what your assignment asks you to consider because TryParse has a genuine need to return two things (the bool of whether it succeeded and the value it parsed if it did succeed). Your requirement is more artificial and uses an out for the sake of academic point; please don't take away from it that out is a good thing to be used often. It (and it's sibling ref) are terrible things that we try to minimize usage of wherever possible.
Once this assignment is over, strive to avoid ever having to use out again until you're fully aware of the implications; once newbies start to think "this is how I return multiple things from a method" they start putting out everywhere. No; the "a method can only return one thing" is perfectly possible to work with, you just make the one thing a method can return an object that holds the multiple things you want to return and then return one of that object. This is Object Oreinted programming after all!
I use out so seldom I don't recall a particular use case in the last 10 years of coding I've done, other than academically contrived examples on SO, also imploring people not to use it
Call the method on that number.
It means call the method, passing the parsed number as the argument
Display the output to the screen.
Piotr's demonstrated this
Create a method with output parameters.
This seems like a tip for how you should achieve step 2; you'll have already done this by the time you get here
Overload a method.
Overloading is providing two or more methods in the same class, that are named the same. The compiler chooses which one to use based on some difference it finds in the argument
This is an example of set of overloads:
void Halve(int number, out int result)
void Halve(int number, int howManyTimes, out int result)
void Halve(double number, out double result)
Overloads can differ by number of arguments, type of arguments, or both. Incidentally, the first two above are what I would perhaps recommend for your assignment; provide a method Halve that divides by 2 just once, and then provide another method that takes an additional number that is how many times to do the divide.
For extra style points you can have the Halve that divides just once call the method that divides N times, passing 1 for the N argument
Declare a class to be static.
Oof, I do wish educators wouldn't promote static. It's such a pain in the ass because it undoes all the good work we're doing trying to get you to think in terms of multiple instances of the same type of object. It also makes me wonder more about the earlier mentioned extension method
I'd "bypass" this one by making the Program class that holds your Main method as static
If you need to return value from method you can either:
Use return kind (which is forbidden in your assigment)
Use ref / out arguments (which allows, for example, returning more than one value without using Tuples).
Example (written without testing!):
// out - means that parameter will be passed out of method
public void Output(int number1, int number2, out int result)
{
result = number1 + number2;
}
public void AddNumbers()
{
int ret; // Need to define variable to hold the result
Output(2, 5, out ret); // Actual call. Note the out keyword
Console.WriteLine("2 + 5 = " + ret);
}

way to define functions in parameters in order to pass one, out of two, functions as an argument

My program had a simple function newline() that would provide an int value to a int variable x.
public void autowordwrap(string wrapthisword)
{
//some code that does things irrelevant to this problem, with the string
x=newline();
//assume x is already declared properly
//do something with value from x
}
Problem started when I introduced a new function sameline()
I want to be able to do any one of these conveniently, at a time:
public void autowordwrap(string wrapthisword)
{
x=newline();
}
or,
public void autowordwrap(string wrapthisword)
{
x=sameline();
}
So, I thought of trying this:
public void autowordwrap(string wrapthisword, Func<void,int> linefunc)
{
x=linefunc;
}
which I can later call on requirement as:
autowordwrap(mystring,newline());
or,
autowordwrap(mystring,sameline());
But it is not quite working out for me!
It says keyword 'void' cannot be used in this context
Problem is:
What I want to do should be simple enough but I'm not quite understanding how it works. I understand that Action<> works for functions without return type and Func<> works for function with a return type.[Reference-1].
What I've gathered so far is:
MSDN tells me: To reference a method that has no parameters and returns void (or in Visual Basic, that is declared as a Sub rather than as a Function), use the Action delegate instead.
Since my newline() function is defined as an int-datatype, and it returns an integer after running, I thought Action<> didn't suit my needs.
This answer has what I need but for the life of me, I couldn't make it work for my specific purpose.
Problem Breakdown
I have two functions newline() and sameline()
I wish to pass any ONE out of the TWO of them as an argument of the function autowordwrap()
which means, in my Main Program, I will be using autowordwrap(somestring, newline()); or autowordwrap(somestring, sameline()); wherever necessary!
both newline() and sameline() are int-datatype functions who return integer value upon being called. For the sake of this problem, lets store it in int x
while trying to solve this, I'm assuming that using Func is used to pass nothing onto the function as an argument while calling example: newline(void) and the int part is used to define the function newline() or any function represented by delegate Func<> as one which returns an int value.
I have realized that what I have seemed to learn must be fundamentally flawed somehow somewhere. Please enlighten me. Reference links would be very helpful too.
Solving this problem in any way is acceptable. You do not need to do this in the way that I may have unintentionally rigidly outlined. Please feel free to explore creative solutions as long as they fulfill the intended purpose in C#
Yes, I acknowledge that THIS is a possible duplicate of this question but I couldn't make much sense of the helpful answer posted over there. Assuming, this will be the case for many future readers, I'm making this question and linking it to that question so that it may be helpful to people who'll face this same problem in the future.
Endnote:
This Question has been solved! The marked answer lays down the way for doing this and there is also some great explanation in the answers. If you are facing some errors while solving a similar question of this nature, you might be able to fix those my looking over screenshots of my own errors. They're here in the revision section no.4
Func<T> has to return some thing, it cannot be void, you have to use Action<T>, if you don't want to return anything.
and if you don't want to pass any input argument to the Func<T>, then you just need one parameter which is return type like:
Func<int> linefunc
you cannot define input type parameter for Func<T,TResult> as void, instead of that just remove the input type parameter of it,
your method definition would look like :
public void autowordwrap(string wrapthisword, Func<int> linefunc)
{
x=linefunc();
}
and call it like:
autowordwrap(mystring, newline);
autowordwrap(mystring, sameline);
You're very nearly there. There are a couple of issues.
First, from your code you appear to be passing the result of your functions in;
autowordwrap("foo", newline());
In this code, C# will invoke the newline function, getting a result. It will then pass the result of that function -- your int -- as the second parameter to autowordwrap.
What you're wanting to do is pass in the un-invoked function itself;
autowordwrap("foo", newline);
So long as the signature of the newline function is compatible with the signature required by autowordwrap, you'll be able to invoke that function inside autowordwrap.
The second part isn't so much the difference between Func<> and Action<>, but about the generic parameters.
The signature you want is a function which takes no parameters and returns an int. So it's reasonable to try
Func<void, int>
but actually, Func<> can take any number of generic types. All but the last are parameters; the last is the return value. So
Func<string, string, int>
corresponds to a method like
public int MyFunction(string s1, string s2) { return 0; }
What you're trying for is a function of no parameters, equivalent to
public int MyFunction() { reutrn 0; }
So the signature you're looking for is
Func<int>
That is, a function of no parameters, returning int. For clarity,
Action<int>
takes one integer parameter and reutrns nothing, equivalent to
public void MyAction(int myParam) { }
--
Oh, and to clarify;
Func<void, int>
Doesn't work because it's equivalent to writing this in C#
public int MyFunction(void x) {}
which is like saying 'a function which takes one parameter, which is a variable of type 'void''. That doesn't make sense, hence the compiler error.
Since your function doesn't need a delegate, it needs an int, you're better off avoiding delegates altogether, just pass the int value, and do this:
public void autowordwrap(string wrapthisword, int separator)
{
//some code that does things irrelevant to this problem, with the string
// if you need it in "x"
x=separator;
//do something with value from x
}
autowordwrap(mystring,newline());
// or
autowordwrap(mystring,sameline());
The general idea for creating clean high quality code is for a function to accept the value(s) it requires to do its specific task, and not some complex input that is "bigger" then that.

How does 'out' (parameter) work? [duplicate]

If we want to get a value from a method, we can use either return value, like this:
public int GetValue();
or:
public void GetValue(out int x);
I don't really understand the differences between them, and so, don't know which is better. Can you explain me this?
Thank you.
Return values are almost always the right choice when the method doesn't have anything else to return. (In fact, I can't think of any cases where I'd ever want a void method with an out parameter, if I had the choice. C# 7's Deconstruct methods for language-supported deconstruction acts as a very, very rare exception to this rule.)
Aside from anything else, it stops the caller from having to declare the variable separately:
int foo;
GetValue(out foo);
vs
int foo = GetValue();
Out values also prevent method chaining like this:
Console.WriteLine(GetValue().ToString("g"));
(Indeed, that's one of the problems with property setters as well, and it's why the builder pattern uses methods which return the builder, e.g. myStringBuilder.Append(xxx).Append(yyy).)
Additionally, out parameters are slightly harder to use with reflection and usually make testing harder too. (More effort is usually put into making it easy to mock return values than out parameters). Basically there's nothing I can think of that they make easier...
Return values FTW.
EDIT: In terms of what's going on...
Basically when you pass in an argument for an "out" parameter, you have to pass in a variable. (Array elements are classified as variables too.) The method you call doesn't have a "new" variable on its stack for the parameter - it uses your variable for storage. Any changes in the variable are immediately visible. Here's an example showing the difference:
using System;
class Test
{
static int value;
static void ShowValue(string description)
{
Console.WriteLine(description + value);
}
static void Main()
{
Console.WriteLine("Return value test...");
value = 5;
value = ReturnValue();
ShowValue("Value after ReturnValue(): ");
value = 5;
Console.WriteLine("Out parameter test...");
OutParameter(out value);
ShowValue("Value after OutParameter(): ");
}
static int ReturnValue()
{
ShowValue("ReturnValue (pre): ");
int tmp = 10;
ShowValue("ReturnValue (post): ");
return tmp;
}
static void OutParameter(out int tmp)
{
ShowValue("OutParameter (pre): ");
tmp = 10;
ShowValue("OutParameter (post): ");
}
}
Results:
Return value test...
ReturnValue (pre): 5
ReturnValue (post): 5
Value after ReturnValue(): 10
Out parameter test...
OutParameter (pre): 5
OutParameter (post): 10
Value after OutParameter(): 10
The difference is at the "post" step - i.e. after the local variable or parameter has been changed. In the ReturnValue test, this makes no difference to the static value variable. In the OutParameter test, the value variable is changed by the line tmp = 10;
What's better, depends on your particular situation. One of the reasons out exists is to facilitate returning multiple values from one method call:
public int ReturnMultiple(int input, out int output1, out int output2)
{
output1 = input + 1;
output2 = input + 2;
return input;
}
So one is not by definition better than the other. But usually you'd want to use a simple return, unless you have the above situation for example.
EDIT:
This is a sample demonstrating one of the reasons that the keyword exists. The above is in no way to be considered a best practise.
You should generally prefer a return value over an out param. Out params are a necessary evil if you find yourself writing code that needs to do 2 things. A good example of this is the Try pattern (such as Int32.TryParse).
Let's consider what the caller of your two methods would have to do. For the first example I can write this...
int foo = GetValue();
Notice that I can declare a variable and assign it via your method in one line. FOr the 2nd example it looks like this...
int foo;
GetValue(out foo);
I'm now forced to declare my variable up front and write my code over two lines.
update
A good place to look when asking these types of question is the .NET Framework Design Guidelines. If you have the book version then you can see the annotations by Anders Hejlsberg and others on this subject (page 184-185) but the online version is here...
http://msdn.microsoft.com/en-us/library/ms182131(VS.80).aspx
If you find yourself needing to return two things from an API then wrapping them up in a struct/class would be better than an out param.
There's one reason to use an out param which has not already been mentioned: the calling method is obliged to receive it. If your method produces a value which the caller should not discard, making it an out forces the caller to specifically accept it:
Method1(); // Return values can be discard quite easily, even accidentally
int resultCode;
Method2(out resultCode); // Out params are a little harder to ignore
Of course the caller can still ignore the value in an out param, but you've called their attention to it.
This is a rare need; more often, you should use an exception for a genuine problem or return an object with state information for an "FYI", but there could be circumstances where this is important.
It's preference mainly
I prefer returns and if you have multiple returns you can wrap them in a Result DTO
public class Result{
public Person Person {get;set;}
public int Sum {get;set;}
}
You should almost always use a return value. 'out' parameters create a bit of friction to a lot of APIs, compositionality, etc.
The most noteworthy exception that springs to mind is when you want to return multiple values (.Net Framework doesn't have tuples until 4.0), such as with the TryParse pattern.
You can only have one return value whereas you can have multiple out parameters.
You only need to consider out parameters in those cases.
However, if you need to return more than one parameter from your method, you probably want to look at what you're returning from an OO approach and consider if you're better off return an object or a struct with these parameters. Therefore you're back to a return value again.
I would prefer the following instead of either of those in this simple example.
public int Value
{
get;
private set;
}
But, they are all very much the same. Usually, one would only use 'out' if they need to pass multiple values back from the method. If you want to send a value in and out of the method, one would choose 'ref'. My method is best, if you are only returning a value, but if you want to pass a parameter and get a value back one would likely choose your first choice.
I think one of the few scenarios where it would be useful would be when working with unmanaged memory, and you want to make it obvious that the "returned" value should be disposed of manually, rather than expecting it to be disposed of on its own.
Additionally, return values are compatible with asynchronous design paradigms.
You cannot designate a function "async" if it uses ref or out parameters.
In summary, Return Values allow method chaining, cleaner syntax (by eliminating the necessity for the caller to declare additional variables), and allow for asynchronous designs without the need for substantial modification in the future.
As others have said: return value, not out param.
May I recommend to you the book "Framework Design Guidelines" (2nd ed)? Pages 184-185 cover the reasons for avoiding out params. The whole book will steer you in the right direction on all sorts of .NET coding issues.
Allied with Framework Design Guidelines is the use of the static analysis tool, FxCop. You'll find this on Microsoft's sites as a free download. Run this on your compiled code and see what it says. If it complains about hundreds and hundreds of things... don't panic! Look calmly and carefully at what it says about each and every case. Don't rush to fix things ASAP. Learn from what it is telling you. You will be put on the road to mastery.
Using the out keyword with a return type of bool, can sometimes reduce code bloat and increase readability. (Primarily when the extra info in the out param is often ignored.) For instance:
var result = DoThing();
if (result.Success)
{
result = DoOtherThing()
if (result.Success)
{
result = DoFinalThing()
if (result.Success)
{
success = true;
}
}
}
vs:
var result;
if (DoThing(out result))
{
if (DoOtherThing(out result))
{
if (DoFinalThing(out result))
{
success = true;
}
}
}
There is no real difference. Out parameters are in C# to allow method return more then one value, that's all.
However There are some slight differences , but non of them are really important:
Using out parameter will enforce you to use two lines like:
int n;
GetValue(n);
while using return value will let you do it in one line:
int n = GetValue();
Another difference (correct only for value types and only if C# doesn't inline the function) is that using return value will necessarily make a copy of the value when the function return, while using OUT parameter will not necessarily do so.
Please avoid using out parameters.
Although, they can make sense in certain situations (for example when implementing the Try-Parse Pattern), they are very hard to grasp.
Chances to introduce bugs or side effects by yourself (unless you are very experienced with the concept) and by other developers (who either use your API or may inherit your code) is very high.
According to Microsoft's quality rule CA1021:
Although return values are commonplace and heavily used, the correct application of out and ref parameters requires intermediate design and coding skills. Library architects who design for a general audience should not expect users to master working with out or ref parameters.
Therefore, if there is not a very good reason, please just don't use out or ref.
See also:
Is using "out" bad practice
https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1021
Both of them have a different purpose and are not treated the same by the compiler. If your method needs to return a value, then you must use return. Out is used where your method needs to return multiple values.
If you use return, then the data is first written to the methods stack and then in the calling method's. While in case of out, it is directly written to the calling methods stack. Not sure if there are any more differences.
out is more useful when you are trying to return an object that you declare in the method.
Example
public BookList Find(string key)
{
BookList book; //BookList is a model class
_books.TryGetValue(key, out book) //_books is a concurrent dictionary
//TryGetValue gets an item with matching key and returns it into book.
return book;
}
return value is the normal value which is returned by your method.
Where as out parameter, well out and ref are 2 key words of C# they allow to pass variables as reference.
The big difference between ref and out is, ref should be initialised before and out don't
I suspect I'm not going to get a look-in on this question, but I am a very experienced programmer, and I hope some of the more open-minded readers will pay attention.
I believe that it suits object-oriented programming languages better for their value-returning procedures (VRPs) to be deterministic and pure.
'VRP' is the modern academic name for a function that is called as part of an expression, and has a return value that notionally replaces the call during evaluation of the expression. E.g. in a statement such as x = 1 + f(y) the function f is serving as a VRP.
'Deterministic' means that the result of the function depends only on the values of its parameters. If you call it again with the same parameter values, you are certain to get the same result.
'Pure' means no side-effects: calling the function does nothing except computing the result. This can be interpreted to mean no important side-effects, in practice, so if the VRP outputs a debugging message every time it is called, for example, that can probably be ignored.
Thus, if, in C#, your function is not deterministic and pure, I say you should make it a void function (in other words, not a VRP), and any value it needs to return should be returned in either an out or a ref parameter.
For example, if you have a function to delete some rows from a database table, and you want it to return the number of rows it deleted, you should declare it something like this:
public void DeleteBasketItems(BasketItemCategory category, out int count);
If you sometimes want to call this function but not get the count, you could always declare an overloading.
You might want to know why this style suits object-oriented programming better. Broadly, it fits into a style of programming that could be (a little imprecisely) termed 'procedural programming', and it is a procedural programming style that fits object-oriented programming better.
Why? The classical model of objects is that they have properties (aka attributes), and you interrogate and manipulate the object (mainly) through reading and updating those properties. A procedural programming style tends to make it easier to do this, because you can execute arbitrary code in between operations that get and set properties.
The downside of procedural programming is that, because you can execute arbitrary code all over the place, you can get some very obtuse and bug-vulnerable interactions via global variables and side-effects.
So, quite simply, it is good practice to signal to someone reading your code that a function could have side-effects by making it non-value returning.

Can someone distill into proper English what a delegate is?

Can someone please break down what a delegate is into a simple, short and terse explanation that encompasses both the purpose and general benefits? I've tried to wrap my head around this and it's just not sinking in.
I have a function:
public long GiveMeTwoTimesTwo()
{
return 2 * 2;
}
This function sucks. What if I want 3 * 3?
public long GiveMeThreeTimesThree()
{
return 3 * 3;
}
Too much typing. I'm lazy!
public long SquareOf(int n)
{
return n * n;
}
My SquareOf function doesn't care what n is. It will operate properly for any n passed in. It doesn't know exactly what number n is, but it does know that n is an integer. You can't pass "Haha not an integer" into SquareOf.
Here's another function:
public void DoSomethingRad()
{
int x = 4;
long y = SquareOf(x);
Console.WriteLine(y);
}
Contrary to its name, DoSomethingRad doesn't actually do anything rad. However, it does write the SquareOf(4) which is 16. Can we change it to be less boring?
public void DoSomethingRad(int numberToSquare)
{
long y = SquareOf(numberToSquare);
Console.WriteLine(y);
}
DoSomethingRad is clearly still pretty fail. But at least now we can pass in a number to square, so it won't write 16 every time. (It'll write 1, or 4, or 9, or 16, or... zzzz still kinda boring).
It'd be nice if there was a way to change what happens to the number passed in. Maybe we don't want to square it; maybe we want to cube it, or subtract it from 69 (number chosen at random from my head).
On further inspection, it seems as though the only part of SquareOf that DoSomethingRad cares about is that we can give it an integer (numberToSquare) and that it gives us a long (because we put its return value in y and y is a long).
public long CubeOf(int n)
{
return n * n * n;
}
public void DoSomethingLeet(int numberToSquare)
{
long y = CubeOf(numberToSquare);
Console.WriteLine(y);
}
See how similar DoSomethingLeet is to DoSomethingRad? If only there was a way to pass in behavior (DoX()) instead of just data (int n)...
So now if we want to write a square of a number, we can DoSomethingRad and if we want to write the cube of a number, we can DoSomethingLeet. So if we want to write the number subtracted from 69, do we have to make another method, DoSomethingCool? No, because that takes too damn much typing (and more importantly, it hinders our ability to alter interesting behavior by changing only one aspect of our program).
So we arrive at:
public long Radlicious(int doSomethingToMe, Func<int, long> doSomething)
{
long y = doSomething(doSomethingToMe);
Console.WriteLine(y);
}
We can call this method by writing this:
Radlicious(77, SquareOf);
Func<int, long> is a special kind of delegate. It stores behavior that accepts integers and spits out longs. We're not sure what the method it points to is going to do with any given integer we pass; all we know is that, whatever happens, we are going to get a long back.
We don't have to give any parameters to SquareOf because Func<int, long> describes behavior, not data. Calling Radlicious(77, SquareOf) just gives Radlicious the general behavior of SquareOf ("I take a number and return its square"), not what SquareOf will do to any specific integer.
Now if you have understood what I am saying, then you have already one-upped me, for I myself don't really get this stuff.
* END ANSWER, BEGIN WANDERING IDIOCY *
I mean, it seems like ints could be perceived as just really boring behavior:
static int Nine()
{
return 9;
}
That said, the line between what is data and behavior appears to blur, with what is normally perceived as data is simply boring-ass behavior.
Of course, one could imagine super "interesting" behavior, that takes all sorts of abstract parameters, but requires a ton of information to be able to call it. What if it required us to provide the source code that it would compile and run for us?
Well, then our abstraction seems to have gotten us all the way back to square one. We have behavior so abstract it requires the entire source code of our program to determine what it's going to do. This is fully indeterminate behavior: the function can do anything, but it has to be provided with everything to determine what it does. On the other hand, fully determinate behavior, such as Nine(), doesn't need any additional information, but can't do anything other than return 9.
So what? I don't know.
In the simplest possible terms, it's essentially a pointer to a method.
You can have a variable that holds a delegate type (just like you would have an int variable that can hold an int type). You can execute the method that the delegate points to by simply calling your variable like a function.
This allows you to have variable functions just like you might have variable data. Your object can accept delegates from other objects and call them, without having to define all the possible functions itself.
This comes in very handy when you want an object to do things based on user specified criteria. For example, filtering a list based on a user-defined true/false expression. You can let the user specify the delegate function to use as a filter to evaluate each list item against.
A delegate is a pointer to a method. You can then use your delegate as a parameter of other methods.
here is a link to a simple tutorial.
The question I had was 'So, why would I want to do that?' You won't really 'get it' until you solve a programming problem with them.
It's interesting that no-one has mentioned one of key benefits of delegation - it's preferable to sub-classing when you realise that inheritance is not a magic bullet and usually creates more problems than it solves. It is the basis of many design patterns, most notably the strategy pattern.
A delegate instance is a reference to a method. The reason they are useful is that you can create a delegate that is tied to a particular method on a particular instance of a type. The delegate instance allows you to invoke that method on that particular instance even if the object on which you will invoke the method has left your lexical scope.
The most common use for delegate instances like this is to support the concept of callbacks at the language level.
It simply references a method. They come in great use with working with cross threading.
Here is an example right out of my code.
//Start our advertisiment thread
rotator = new Thread(initRotate);
rotator.Priority = ThreadPriority.Lowest;
rotator.Start();
#region Ad Rotation
private delegate void ad();
private void initRotate()
{
ad ad = new ad(adHelper);
while (true)
{
this.Invoke(ad);
Thread.Sleep(30000);
}
}
private void adHelper()
{
List<string> tmp = Lobby.AdRotator.RotateAd();
picBanner.ImageLocation = #tmp[0].ToString();
picBanner.Tag = tmp[1].ToString();
}
#endregion
If you didnt use a delegate you wouldn't be able to crossthread and call the Lobby.AdRotator function.
Like others have said, a delegate is a reference to a function. One of the more beneficial uses(IMO) is events. When you register an event you register a function for the event to invoke, and delegates are perfect for this task.
In the most basic terms, a delegate is just a variable that contains (a reference to) a function. Delegates are useful because they allow you to pass a function around as a variable without any concern for "where" the function actually came from.
It's important to note, of course, that the function isn't being copied when it's being bundled up in a variable; it's just being bound by reference. For example:
class Foo
{
public string Bar
{
get;
set;
}
public void Baz()
{
Console.WriteLine(Bar);
}
}
Foo foo = new Foo();
Action someDelegate = foo.Baz;
// Produces "Hello, world".
foo.Bar = "Hello, world";
someDelegate();
In most simplest terms, the responsibility to execute a method is delegated to another object. Say the president of some nation dies and the president of USA is supposed to be present for the funeral with condolences message. If the president of USA is not able to go, he will delegate this responsibility to someone either the vice-president or the secretary of the state.
Same goes in code. A delegate is a type, it is an object which is capable of executing the method.
eg.
Class Person
{
public string GetPersonName(Person person)
{
return person.FirstName + person.LastName;
}
//Calling the method without the use of delegate
public void PrintName()
{
Console.WriteLine(GetPersonName(this));
}
//using delegate
//Declare delegate which matches the methods signature
public delegate string personNameDelegate(Person person);
public void PrintNameUsingDelegate()
{
//instantiate
personNameDelegate = new personNameDelegate(GetPersonName);
//invoke
personNameDelegate(this);
}
}
The GetPersonName method is called using the delegate object personNameDelegate.
Alternatively we can have the PrintNameUsingDelegate method to take a delegate as a parameter.
public void PrintNameUsingDelegate(personNameDelegate pnd, Person person)
{
pnd(person);
}
The advantage is if someone want to print the name as lastname_firstname, s/he just has to wrap that method in personNameDelegate and pass to this function. No further code change is required.
Delegates are specifically important in
Events
Asynchronous calls
LINQ (as lambda expressions)
If you were going to delegate a task to someone, the delegate would be the person who receives the work.
In programming, it's a reference to the block of code which actually knows how to do something. Often this is a pointer to the function or method which will handle some item.
In the absolute most simplest terms I can come up with is this: A delegate will force the burdens of work into the hands of a class that pretty much knows what to do. Think of it as a kid that doesn't want to grow up to be like his big brother completely but still needs his guidance and orders. Instead of inheriting all the methods from his brother (ie subclassing), he just makes his brother do the work or The little brother does something that requires actions to be taken by the big brother. When you fall into the lines of Protocols, the big brother defines what is absolutely required, or he might give you flexibility to choose what you want to make him do in certain events (ie informal and formal protocols as outlined in Objective-C).
The absolute benefit of this concept is that you do not need to create a subclass. If you want something to fall in line, follow orders when an event happens, the delegate allows a developed class to hold it's hand and give orders if necessary.

Should you declare methods using overloads or optional parameters in C# 4.0?

I was watching Anders' talk about C# 4.0 and sneak preview of C# 5.0, and it got me thinking about when optional parameters are available in C# what is going to be the recommended way to declare methods that do not need all parameters specified?
For example something like the FileStream class has about fifteen different constructors which can be divided into logical 'families' e.g. the ones below from a string, the ones from an IntPtr and the ones from a SafeFileHandle.
FileStream(string,FileMode);
FileStream(string,FileMode,FileAccess);
FileStream(string,FileMode,FileAccess,FileShare);
FileStream(string,FileMode,FileAccess,FileShare,int);
FileStream(string,FileMode,FileAccess,FileShare,int,bool);
It seems to me that this type of pattern could be simplified by having three constructors instead, and using optional parameters for the ones that can be defaulted, which would make the different families of constructors more distinct [note: I know this change will not be made in the BCL, I'm talking hypothetically for this type of situation].
What do you think? From C# 4.0 will it make more sense to make closely related groups of constructors and methods a single method with optional parameters, or is there a good reason to stick with the traditional many-overload mechanism?
I'd consider the following:
Do you need your code to be used from languages which don't support optional parameters? If so, consider including the overloads.
Do you have any members on your team who violently oppose optional parameters? (Sometimes it's easier to live with a decision you don't like than to argue the case.)
Are you confident that your defaults won't change between builds of your code, or if they might, will your callers be okay with that?
I haven't checked how the defaults are going to work, but I'd assume that the default values will be baked into the calling code, much the same as references to const fields. That's usually okay - changes to a default value are pretty significant anyway - but those are the things to consider.
When a method overload normally performs the same thing with a different number of arguments then defaults will be used.
When a method overload performs a function differently based on its parameters then overloading will continue to be used.
I used optional back in my VB6 days and have since missed it, it will reduce a lot of XML comment duplication in C#.
I've been using Delphi with optional parameters forever. I've switched to using overloads instead.
Because when you go to create more overloads, you'll invariably conflict with an optional parameter form, and then you'll have to convert them to non-optional anyway.
And I like the notion that there's generally one super method, and the rest are simpler wrappers around that one.
I will definitely be using the optional parameters feature of 4.0. It gets rid of the ridiculous ...
public void M1( string foo, string bar )
{
// do that thang
}
public void M1( string foo )
{
M1( foo, "bar default" ); // I have always hated this line of code specifically
}
... and puts the values right where the caller can see them ...
public void M1( string foo, string bar = "bar default" )
{
// do that thang
}
Much more simple and much less error prone. I've actually seen this as a bug in the overload case ...
public void M1( string foo )
{
M2( foo, "bar default" ); // oops! I meant M1!
}
I have not played with the 4.0 complier yet, but I would not be shocked to learn that the complier simply emits the overloads for you.
Optional parameters are essentially a piece of metadata which directs a compiler that's processing a method call to insert appropriate defaults at the call site. By contrast, overloads provide a means by which a compiler can select one of a number of methods, some of which might supply default values themselves. Note that if one tries to call a method that specifies optional parameters from code written in a language which doesn't support them, the compiler will require that the "optional" parameters be specified, but since calling a method without specifying an optional parameter is equivalent to calling it with a parameter equal to the default value, there's no obstacle to such languages calling such methods.
A significant consequence of binding of optional parameters at the call site is that they will be assigned values based upon the version of the target code which is available to the compiler. If an assembly Foo has a method Boo(int) with a default value of 5, and assembly Bar contains a call to Foo.Boo(), the compiler will process that as a Foo.Boo(5). If the default value is changed to 6 and assembly Foo is recompiled, Bar will continue to call Foo.Boo(5) unless or until it is recompiled with that new version of Foo. One should thus avoid using optional parameters for things that might change.
It can be argued whether optional arguments or overloads should be used or not, but most importantly, each have their own area where they are irreplaceable.
Optional arguments, when used in combination with named arguments, are extremely useful when combined with some long-argument-lists-with-all-optionals of COM calls.
Overloads are extremely useful when method is able to operate on many different argument types (just one of examples), and does castings internally, for instance; you just feed it with any data type that makes sense (that is accepted by some existing overload). Can't beat that with optional arguments.
In many cases optional parameters are used to switch execution. For example:
decimal GetPrice(string productName, decimal discountPercentage = 0)
{
decimal basePrice = CalculateBasePrice(productName);
if (discountPercentage > 0)
return basePrice * (1 - discountPercentage / 100);
else
return basePrice;
}
Discount parameter here is used to feed the if-then-else statement. There is the polymorphism that wasn't recognized, and then it was implemented as an if-then-else statement. In such cases, it is much better to split the two control flows into two independent methods:
decimal GetPrice(string productName)
{
decimal basePrice = CalculateBasePrice(productName);
return basePrice;
}
decimal GetPrice(string productName, decimal discountPercentage)
{
if (discountPercentage <= 0)
throw new ArgumentException();
decimal basePrice = GetPrice(productName);
decimal discountedPrice = basePrice * (1 - discountPercentage / 100);
return discountedPrice;
}
In this way, we have even protected the class from receiving a call with zero discount. That call would mean that the caller thinks that there is the discount, but in fact there is no discount at all. Such misunderstanding can easily cause a bug.
In cases like this, I prefer not to have optional parameters, but to force the caller explicitly select the execution scenario that suits its current situation.
The situation is very similar to having parameters that can be null. That is equally bad idea when implementation boils to statements like if (x == null).
You can find detailed analysis on these links: Avoiding Optional Parameters and Avoiding Null Parameters
One caveat of optional parameters is versioning, where a refactor has unintended consequences. An example:
Initial code
public string HandleError(string message, bool silent=true, bool isCritical=true)
{
...
}
Assume this is one of many callers of the above method:
HandleError("Disk is full", false);
Here the event is not silent and is treated as critical.
Now let's say after a refactor we find that all errors prompt the user anyway, so we no longer need the silent flag. So we remove it.
After refactor
The former call still compiles, and let's say it slips through the refactor unchanged:
public string HandleError(string message, /*bool silent=true,*/ bool isCritical=true)
{
...
}
...
// Some other distant code file:
HandleError("Disk is full", false);
Now false will have an unintended effect, the event will no longer be treated as critical.
This could result in a subtle defect, since there will be no compile or runtime error (unlike some other caveats of optionals, such as this or this).
Note that there are many forms of this same problem. One other form is outlined here.
Note also that strictly using named parameters when calling the method will avoid the issue, such as like this: HandleError("Disk is full", silent:false). However, it may not be practical to assume that all other developers (or users of a public API) will do so.
For these reasons I would avoid using optional parameters in a public API (or even a public method if it might be used widely) unless there are other compelling considerations.
One of my favourites aspects of optional parameters is that you see what happens to your parameters if you do not provide them, even without going to the method definition. Visual Studio will simply show you the default value for the parameter when you type the method name. With an overload method you are stuck with either reading the documentation (if even available) or with directly navigating to the method's definition (if available) and to the method that the overload wraps.
In particular: the documentation effort may increase rapidly with the amount of overloads, and you will probably end up copying already existing comments from the existing overloads. This is quite annoying, as it does not produce any value and breaks the DRY-principle). On the other hand, with an optional parameter there's exactly one place where all the parameters are documented and you see their meaning as well as their default values while typing.
Last but not least, if you are the consumer of an API you may not even have the option of inspecting the implementation details (if you don't have the source code) and therefore have no chance to see to which super method the overloaded ones are wrapping. Thus you're stuck with reading the doc and hoping that all default values are listed there, but this is not always the case.
Of course, this is not an answer that handles all aspects, but I think it adds one which has not be covered so far.
I'm looking forward to optional parameters because it keeps what the defaults are closer to the method. So instead of dozens of lines for the overloads that just call the "expanded" method, you just define the method once and you can see what the optional parameters default to in the method signature. I'd rather look at:
public Rectangle (Point start = Point.Zero, int width, int height)
{
Start = start;
Width = width;
Height = height;
}
Instead of this:
public Rectangle (Point start, int width, int height)
{
Start = start;
Width = width;
Height = height;
}
public Rectangle (int width, int height) :
this (Point.Zero, width, height)
{
}
Obviously this example is really simple but the case in the OP with 5 overloads, things can get crowded real quick.
While they are (supposedly?) two conceptually equivalent ways available for you to model your API from scratch, they unfortunately have some subtle difference when you need to consider runtime backward compatibility for your old clients in the wild. My colleague (thanks Brent!) pointed me to this wonderful post: Versioning issues with optional arguments. Some quote from it:
The reason that optional parameters were introduced to C# 4 in the
first place was to support COM interop. That’s it. And now, we’re
learning about the full implications of this fact. If you have a
method with optional parameters, you can never add an overload with
additional optional parameters out of fear of causing a compile-time
breaking change. And you can never remove an existing overload, as
this has always been a runtime breaking change. You pretty much need
to treat it like an interface. Your only recourse in this case is to
write a new method with a new name. So be aware of this if you plan to
use optional arguments in your APIs.
To add a no-brainer when to use an overload instead of optionals:
Whenever you have a number of parameters that only make sense together, do not introduce optionals on them.
Or more generally, whenever your method signatures enable usage patterns which don't make sense, restrict the number of permutations of possible calls. E.g., by using overloads instead of optionals (this rule also holds true when you have several parameters of the same datatype, by the way; here, devices like factory methods or custom data types can help).
Example:
enum Match {
Regex,
Wildcard,
ContainsString,
}
// Don't: This way, Enumerate() can be called in a way
// which does not make sense:
IEnumerable<string> Enumerate(string searchPattern = null,
Match match = Match.Regex,
SearchOption searchOption = SearchOption.TopDirectoryOnly);
// Better: Provide only overloads which cannot be mis-used:
IEnumerable<string> Enumerate(SearchOption searchOption = SearchOption.TopDirectoryOnly);
IEnumerable<string> Enumerate(string searchPattern, Match match,
SearchOption searchOption = SearchOption.TopDirectoryOnly);
Both Optional parameter , Method overload have there own advantage or disadvantage.it depends on your preference to choose between them.
Optional Parameter:
available only in .Net 4.0.
optional parameter reduce your code size.
You can't define out and ref parameter
overloaded methods:
You can Define Out and ref parameters.
Code size will increase but overloaded method's are easy to understand.

Categories

Resources