This question already has answers here:
Setting the default value of a C# Optional Parameter
(3 answers)
Passing an empty array as default value of an optional parameter [duplicate]
(3 answers)
Closed 9 years ago.
The below code would be quite cool if it worked. However, I can't get it to compile, so I'm assuming this isn't going to work in any form?
public void foo(char[] bar = new char[]{'a'})
{
}
The next-best option is to just do
public void foo(char[] bar = null)
{
if (bar==null)
bar = new {'a'};
}
No it's not possible. The default value needs to be a compile-time constant. The default value will be inserted into the caller, not the callee. Your code would be a problem if the caller has no access to the methods used to create your default value.
But you can use simple overloads:
public void foo(char[] bar)
{
}
public void foo()
{
foo(new char[]{'a'});
}
No, because optional parameter default values need to be constant.
Why do optional parameters in C# 4.0 require compile-time constants?
That will never work because char[] is not a value type but rather a reference type. Only value types can have constants assigned to them in optional parameters. You cannot have a reference to an object (such as an array) at compile time. (Null is the only valid value for an optional reference type.)
Other comments apply as well, but also consider that, since the default value is inserted into the caller at compile time, changing the default value at some later date will not change the value in the caller code (assuming it's being called from another assembly.) Because of this, what you propose as a work-around, or next-best option, is in fact a better practice.
only with value types you have the possibility to set the default value of a parameter to compile-time constants (making it optional). For reference types, only strings have that ability. Other types can only be set to null.
edit: thanks #Martinho Fernandes for pointing that out. For value types, only compile-time constants are allowed
Related
This question already has answers here:
Impossible to use ref and out for first ("this") parameter in Extension methods?
(6 answers)
Closed 7 years ago.
I have created a void extension method which can be used with decimal data types. I wanted to be able to modify the this parameter variable inside the scope of the method. This is the code for my extension method:
public static void SetAndConvertIfHasValue(this decimal assignTo, double? valueToAssign)
{
if (valueToAssign.HasValue)
assignTo = (decimal)valueToAssign.Value;
else
assignTo = 0m;
}
However, when I call it:
data.MyDecimalToSet.SetAndConvertIfHasValue(nullableDouble);
data.MyDecimalToSet is not set to the value in nullableDouble if it has one.
In debug if I step into the extension method, assignTo is changed to the correct value, this change just doesn't bubble up to data.MyDecimalToSet.
At this point I have decided to use a standard method rather than an extension method as a solution to this problem, however I was curious as to why this doesn't work? And whether there is a way around it, or if it simply is impossible?
This doesn't work because when you pass a variable to a method, a copy of that variable is passed. When you operate on that copy, you will only be changing the copy.
Note that this will happen regardless of whether the variable is a reference or a value type. However, if you pass a reference type, you can change the contents of the reference type, since the reference passed to the method will be copied, but it will still reference the original object.
(decimal is a value type, so that last point does not apply to it.)
You are doing it the right way if you use a standard method instead.
This question already has answers here:
Is it possible to pass properties as "out" or "ref" parameters?
(3 answers)
Closed 8 years ago.
Why exactly I can't use an AutoProperty as an out parameter?
For example (This gives me an error):
public int HeightValue { get; set; }
//...
private void Parse()
{
int.TryParse(WidthText.Text, out HeightValue);
//Intellisense Error: out argument is not classified as a variable
}
Possibly because properties are in essence methods and you need to give a field to set the value to the out parameter. You can define a backing field for your property and give its value as the out parameter.
See Jon Skeet's answer here:
Passing a property as an 'out' parameter in C#
The method itself needs a variable as the out parameter. It's got to have a storage location it can just write values to. Not a property, not anything it needs to invoke: just a storage location. A property doesn't satisfy that requirement. So there's nothing that can be done by the compiler in the method to allow this.
This question already has answers here:
What is the purpose of a question mark after a value type (for example: int? myVariable)?
(9 answers)
Closed 9 years ago.
i have seen the following code in an c# example:
public void AddScreen(GameScreen screen, PlayerIndex? controllingPlayer)
{
screen.ControllingPlayer = controllingPlayer;
screen.ScreenManager = this;
screen.IsExiting = false;
}
and i have no clue what the ? is doing after PlayerIndex, it is an enum, and in the class every notice of it is with the ? behind it.
my question: what does it do, what is it called and why would you use it.
I have googled this, but it didn't get me far since i dont know the name of this coding and google filters out the question mark in the search query
The ? makes PlayerIndex a NULLABLE type.
That way controllingPlayer can be NULL even if it is an enum or a basic type like int.
The ? is a nullable type. This means that controllingPlayer can contain null or a value.
To check whether there is a value associated with the variable, you can use HasValue. To retrieve the actual value, use Value
if ( controllingPlayer.HasValue )
// now do something with controllingPlayer.Value
The question mark denotes that PlayerIndex is treated as a nullable type.
Probably PlayerIndex is not a class or struct but an enum or alias for int or something like that. If it's an alias, you should find something like this in the code:
using PlayerIndex= System.Int32;
It's short for Nullable<PlayerIndex> which means that you can pass a PlayerIndex value or null.
The ? is indicating that controllingPlayer can be null. It could also be written as Nullable<PlayerIndex> controllerPlayer.
This is useful when working with valuetypes which can not be null, like reference types can be. If you have a regular int, you cannot differentiate between a variable that is given the value 0 and a variable that is never written to. By wrapping it in a Nullable<>, you can now check if it has a value or not:
int notNullable; //will be initialized to 0 by default.
int? nullable; //will be initialized to null by default.
if (nullable.HasValue) //Do something if the variable has been given a value
{
return nullable.Value; //get the actual int-value
}
See msdn documentation for nullable types: http://msdn.microsoft.com/en-us/library/1t3y8s4s(v=vs.80).aspx
It means that the value type in question is a nullable type
Appending ? to a type when defining something it is shorthand for wrapping in a Nullable<T> (see Nullable Types for further details). This means that value types, usually not able to express nullity, can be checked for a non-value instead of always resorting to their default (i.e., an int, rather than default to 0, will default to null).
You may check whether or not the thing has a value, and access the value thusly:
var hasValue = nullableThing.HasValue;
var underlyingValue = nullableThing.Value;
PlayerIndex? indicate that varible can be null value. The syntax T? is shorthand for System.Nullable, where T is a value type. please refer to Nullable Types (C# Programming Guide).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference between Property and Field in C#
I know it is a very basic question but I cannot read any valid answer after searching
E.g
public string abc;
public string abc { get; set; }
Please describe this.
(About my terminology: "field" = public variable, "property" = get/set)
One thing to be mentioned additionally to the differences in usage: A property, unlike a field, gets compiled to a method (I think it's called something like get_abc internally). Declaring an auto property from beginning on has therefor two advantages:
1) No problems with reflection. If some reflection code is based on the value being a field, and later you think "well, now I'd like to add null testing" and change to a property, then the reflection code will eventally fail (unless you expected that in the reflection, but that would be extra effort for nothing imho)
2) "Warning" of possible side effects. Fields can only change their values, methods can do arbitrary things to a class. So, declaring a property from beginning on signalizes the possibility of other changes happening in the background. (Of course one shouldn't do weird stuff in a setter, but sometimes it isn't impractical to get additional initialization from one value provided; e.g. measuring the length of a list)
I also would say that it's good style to use properties wherever possible. Especially for the two reasons provided, but also for consistency.
Variables store direct value but property are a window to your class and its variables.
Even though they work the same(almost), one very good thing with field is that if you want to do some extra work with field (like validation or doing any calculations) you can do so.
This will explain you
public string _abc;
public string abc
{
get
{
return _abc;
};
set
{
if (value == null)
_abc = "";
else
_abc = value;
};
}
Here if null is passed to property abc then it will be checked it and an empty value will be assigned to _abc. otherwise value.
If we wanted this with a variable. every where we had to do this.
if(foo == null) // here foo is some string
_abc = ""
else
_abc = foo;
with property this can be done like
abc = foo;
Now it will check for in the set section of property.
Properties can contain some code on setting/getting the value. Public variables can't and will not contain any code when you access them. This is a huge difference.
Using a property you're saying to whomever uses you're code that there might be some code behind the value now or in the future.
Using a public variable you're saying its just a boring old field that will contain some value.
One reason for using an auto property instead of a Field is compatibility.
For example, when you assign a field, the CLR does just that. It sets the field.
When you have a property (auto or not), and you type
someObject.Whatever = "Value";
it looks like you are assigning a field, but in reality, the C# compiler inserts something like this for you:
someObject.set_Whatever("Value");
That's not the same as setting a field. And if you have a field and change it to a property later (e.g. if you want to implement change notifications or things like that), you will have to recompile all assemblies that used the original field, since assigning a Field requires different code than setting a property (no matter if auto or not).
There is almost never a reason to use a public field. Automatic properties can be inlined at runtime, so there would be no performance difference. And they leave the possibility open to add additional logic to your get / set methods without having to recompile dependent assemblies.
Same difference as a property over public variable such as property support binding but variable not.
MSDN's VS2010 Named and Optional Arguments (C# Programming Guide) tells us about optional parameters in C#, showing code like I'd expect:
public void ExampleMethod(int required,
string optionalstr = "default string",
int optionalint = 10)
Ok, but it also says:
You can also declare optional
parameters by using the .NET
OptionalAttribute class.
OptionalAttribute parameters do not
require a default value.
I read MSDN's OptionalAttribute page, and done searches online (which shows lots of people claiming OptionalAttribute parameters can't be consumed by C# -- I'm guessing these comments were made before C# 4?), but I can't find the answer to two questions:
If I use OptionalAttribute to define a C# parameter as optional:
what value will be used if I call that method and don't specify that parameter's value?
will that value be evaluated at compile time or runtime?
The rules are this:
For parameters of type object, Type.Missing is passed.
For other reference types, null is passed.
For value types, the default of the value type is passed.
For Nullable<T> this means that you will get a Nullable<T> instance which is equal to null (the HasValue property will return false)
Note that in the case of everything except parameters of type object, it's the equivalent of default(T).
I was a little surprised, as the C# 4.0 specification didn't indicate what the outcome would be, and I'd expect it to be there.
Also (as indicated by Scott Rippey in the comments), this is evaluated at compile-time, this is not a run-time operation, meaning that if you have calls to this method in other assemblies which are already deployed, and you change the optional value, the default passed to the method will not change unless you compile everything that makes the call against the method in the assembly.