Is there any way in C# to create a variable inline?
Something like this:
int x = int.TryParse("5", out new int intOutParameter) ? intOutParameter : 0;
Don´t you think that this is more useful than creating a variable outside and then never use it again?
That syntax – called declaration expressions – was on the proposed feature list for the next version of C# (version 6).
You're not the only one to think it is useful. For instance making a complete TryParse call an expression (no need for a statement to declare the variable).
However it has been dropped from the ongoing work to C#6.
I'm sure I'm not the only one hoping it will make a return in a future version.It is included in C#7 as a declaration (no need for new):
int x = int.TryParse("5", out int intOutParameter) ? intOutParameter : 0;
Inline declarations for out params is a new suggested feature in C# that might be standard one day, see e.g. Probable C# 6.0 features illustrated, section 9. The expected/proposed syntax:
int.TryParse("5", out int x); // this declares (and assigns) a new variable x
Edit: This out variable syntax was eventually included in C# 7.0 (Visual Studio 2017); you can also use out var x.
Addition: People come up with fun extension methods. I tried to make a generic one:
public delegate bool TryParser<TResult>(string s, out TResult result);
public static class FunExtensions
{
public static T TryParse<T>(this string str, TryParser<T> tryParser)
{
T outResult;
tryParser(str, out outResult);
return outResult;
}
}
This can be used like this:
var x = "5".TryParse<int>(int.TryParse);
var y = "01/01".TryParse<DateTime>(DateTime.TryParse);
var z = "bad".TryParse<decimal>(decimal.TryParse);
and so on. I was hoping the compiler would infer T from usage, so that one could say simply:
var x = "5".TryParse(int.TryParse); // won't compile
but it appears you have to explicitly specify the type argument to the method.
As a workaround you could create an extension:
public static int TryParse(this string input, int defaultValue = default(int))
{
int intOutParameter;
bool parsable = int.TryParse(input, out intOutParameter);
if (parsable)
return intOutParameter;
else
return defaultValue;
}
Then you don't even need an out-parameter:
int parsed = "5".TryParse(0);
Based on OP request:
private static bool IsIntValid(string str)
{
int i = 0;
return int.TryParse(str, out i);
}
Granted not the most cleverest approach however, the simplest I guess :) Can wrap this in an extension method also perhaps.
You can also use a temporary storage for all methods.
public static class Tmp<T>
{
[ThreadStatic]
public static T Value;
}
int x = int.TryParse("5", out Tmp<int>.Value) ? Tmp<int>.Value : 0;
Related
In C# 8.0, Static Local Functions are announced
Can anyone help enlighten me as to why you would want to declare a local function as static?
The reason given in in the article:
to ensure that local function doesn't capture (reference) any variables from the enclosing scope
But:
I don't understand why would you want to ensure that?
Is there any other reason or benefits to declare it static? (performance maybe?)
The example code given in the article is:
int M()
{
int y = 5;
int x = 7;
return Add(x, y);
static int Add(int left, int right) => left + right;
}
I don't understand why would you want to ensure that?
Because it prevents you from shooting yourself in the foot. It forces the local function to be a pure function that does not modify the state of the caller.
This returns false, because the function modifies local variables of its caller:
public bool Is42()
{
int i = 42;
Foo();
return i == 42;
void Foo()
{
i = 21;
}
}
And this doesn't, because it doesn't even compile:
public bool Is42()
{
int i = 42;
Foo();
return i == 42;
static void Foo()
{
i = 21;
}
}
It prevents surprises. Of course in these simple examples the benefit isn't immediately clear, because "well it's obvious that Foo() modifies i", but in larger codebases maintained by multiple people and not properly covered by unit tests, this simple modifier prevents grief.
Capturing variables has a small additional cost as it will generate an internally used type where your captured variables are public fields. Consider a slightly modified example:
int M()
{
int y = 5;
int x = 7;
return Add();
int Add() => x + y;
}
It will actually translate to something like this:
int M()
{
int y = 5;
int x = 7;
var capturedVars = new <>c__DisplayClass0_0 { x = x, y = y };
return <M>g__Add|0_0(ref capturedVars);
}
[CompilerGenerated]
private struct <>c__DisplayClass0_0
{
public int x;
public int y;
}
[CompilerGenerated]
internal static int <M>g__Add|0_0(ref <>c__DisplayClass0_0 class_Ref1) =>
(class_Ref1.x + class_Ref1.y);
This answer from CodeCaster and this separate answer from György Kőszeg individually answer different parts of my question, so I'm bringing them both together to form the full picture for the accepted answer:
For Part 1) of my question, #CodeCaster Says:
Because it prevents you from shooting yourself in the foot. It forces the local function to be a pure function that does not modify the state of the caller.
in larger codebases maintained by multiple people and not properly covered by unit tests, this simple modifier prevents grief
So Answer 1 is: Static Local Functions ensure reliable caller method state.
For Part 2) of my question, #György Kőszeg Says:
Capturing variables has a small additional cost as it will generate an internally used type where your captured variables are public fields
And he goes on to give an example of the produced compiler code via reflector.
So Answer 2 is: Static Local Functions prevent variable capturing. Variable capturing comes at a small cost. So there is a small performance boost by declaring the local function static
I think this is just to ensure correct usage of the variables used in the local function, as the documentation says. In large and complex methods, it can prevent accidental usage of enclosing scope variables if there are variables with the same name in the local function.
It's possible in c# 7 to declare variables for out variables in argument list:
if (int.TryParse(input, out int result))
WriteLine(result);
Is it possible to declare ("non out") variable in argument list? Like this:
if (!string.IsNullOrEmpty(string result=FuncGetStr()))
WriteLine(result);
You can't do it in the argument list, no.
You could use pattern matching for this, but I wouldn't advise it:
if (FuncGetStr() is string result && !string.IsNullOrEmpty(result))
That keeps the declaration within the source code of the if, but the scope of result is still the enclosing block, so I think it would much simpler just to separate out:
// Mostly equivalent, and easier to read
string result = FuncGetStr();
if (!string.IsNullOrEmpty(result))
{
...
}
There are two differences I can think of:
result isn't definitely assigned after the if statement in the first version
string.IsNullOrEmpty isn't even called in the first version if FuncGetStr() returns null, as the is pattern won't match. You could therefore write it as:
if (FuncGetStr() is string result && result != "")
To be utterly horrible, you could do it, with a helper method to let you use out parameters. Here's a complete example. Please note that I am not suggesting this as something to do.
// EVIL CODE: DO NOT USE
using System;
public class Test
{
static void Main(string[] args)
{
if (!string.IsNullOrEmpty(Call(FuncGetStr, out string result)))
{
Console.WriteLine(result);
}
}
static string FuncGetStr() => "foo";
static T Call<T>(Func<T> func, out T x) => x = func();
}
You can assign variables in statements, but the declaration of the variables should be done outside of them. You can't combine them (outside out and pattern matching, as you already indicated in your question).
bool b;
string a;
if (b = string.IsNullOrEmpty(a = "a")){ }
On the why this behavior is different than with out, etc, Damien_The_Unbeliever's comment might be interesting:
The ability to declare out variables inline arises from the awkwardness that it a) has to be a variable rather than a value and b) there's often nothing too useful to do with the value if you declare it before the function is called. I don't see the same motivations for other such uses.
I would like to know if there is simpler way to check a condition and assign the same variable if the condition is false similar to null-coalescing operator (??)
Here is how it can be done now
int i = 0;
...
int j = (i == 0) ? 1 : i;
Can it be made simpler like
int i = 0
...
int j = (i == 0) ?? 1;
I understand it won't work that way since ?? only checks for null. But I'm wondering if it can achieved with a different operator.
You could create an extension method for int types that will do what you want:
public static class Extensions
{
public static int IfZero (this int value, int defaultValue)
{
return value == 0 ? defaultValue : value;
}
public static int ReplaceValue(this int value, int valueToReplace, int replaceWith)
{
return value == valueToReplace ? replaceWith : value;
}
}
Then it could be used throughout your program like:
int i = 0;
int j = i.IfZero(1);
// Or using the more generic method:
int j = i.ReplaceValue(0, 1);
I think what you're looking for is impossible in general (as opposed to when more info is available as I mention below). The reason is that you need 3 pieces of information for the job:
the value to check for
the value to use if true
the value to use if false
The ?? operator gets around that by assuming that 1 is null. But that would mean that you would need a separate operator for every value of 1 that you would want to test for. This is worthwhile for the C# team to write for something as common as null. Not for most things. (Of courses you could write your own for cases you know you need. But it seems like you're looking for something built in.)
In your specific case
Assuming that the minimum has to be 1, you can have:
j = Math.Max(1, i);
In response to those asking why would the OP be looking for simpler code than already very simple code, this might be to reflect the logic behind the action, and therefore be (in a sense) more readable.
No, the language does not offer that.
You can write a generic extension method, though:
public static class CoalescingExtensions
{
public static T IfDefault<T> (this T value, T valueIfDefault)
{
return value.Equals(default(T)) ? valueIfDefault: value;
}
}
The code is using 0 to determine whether or not the variable has been initialized. However, this can create issues since 0 is a valid value for an integer.
If checking for a different default value is acceptable, try using nullable types. This will allow you to use the null coalescing operator.
int? i = null;
...
int j = i?? 1;
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/nullable-types/
First of all, I apologize if this has been asked a thousand times. I read my C# book, I googled it, but I can't seem to find the answer I am looking for, or I am missing the point big time.
I am very confused with the whole boxing/unboxing issue. Say I have fields of different classes, all returning typed variables (e.g. 'double') and I would like to have a variable point to any of these fields. In plain old C I would do something like:
double * newVar;
newVar = &oldVar;
newVar = &anotherVar;
...
I have a timer calls a function and passes the value of the referenced variable:
ChartPlotData(*newVar);
The reason why I am looking for a pointer is because newVar changes at runtime, linked to an Event:
public void checkbox_Clicked(object sender ...)
if (sender == checkbox1) value = &object1.field1;
if (sender == checkbox2) value = &object2.field1;
How can this be done in C#?
EDIT1: Explained purpose of referencing.
EDIT2: Made some incorrect statements, deleted them and shortened the question.
You could have a click event, as suggested in your edit, and then use a delegate to select the data to be passed to the control. I'm not sure if that'll meet your performance requirements though.
ChartPlotData(valueSelector());
// ...
Func<double> valueSelector;
protected void Checkbox_Click(object sender /* ... */)
{
if (sender == checkbox1) valueSelector = () => object1.field1;
if (sender == checkbox2) valueSelector = () => object2.field1;
// ...
}
(If you preferred, and if you're able to, you could overload your ChartPlotData method to accept a Func<double> rather than a plain double, and then invoke the selector delegate lazily inside the method rather than at the call site.)
Simple types and structs are of value type in C#. You can't do anything about it unless as you mentioned you use unsafe modifier. Having said that, your options are limited.
Use object instead of primitive types.
Use arrays of size 1.
Custom generic proxy class encapsulating either of above.
???
You can refer to an existing value type using the ref keyword.
public static void ModifyNumber(ref int i)
{
i += 1;
}
static void Main(string[] args)
{
int num = 4;
ModifyNumber(ref num);
ModifyNumber(ref num);
ModifyNumber(ref num);
ModifyNumber(ref num);
// num now equals 8
}
I am not sure why you need address of the variable. Double is value type and is stored in stack. To pass it by refference into the method just use C# ref keyword.
From cases you have mentioned I personally would prefer something like this:
class Program
{
public class Refferenced<T> where T : struct
{
public T Value { get; set; }
}
static void Main(string[] args)
{
Refferenced<double> x = new Refferenced<double>();
Refferenced<double> y = new Refferenced<double>();
y.Value = 2;
x = y;
x.Value = 5;
Console.WriteLine(x.Value);
Console.WriteLine(y.Value);
y.Value = 7;
Console.WriteLine(x.Value);
Console.WriteLine(y.Value);
Console.ReadKey();
}
It is similar to C# NullAble types.
In C++ I can do this:
int flag=0,int1=0,int2=1;
int &iRef = (flag==0?int1:int2);
iRef +=1;
with the effect that int1 gets incremented.
I have to modify some older c# code and it would be really helpful if I could do something similar, but I'm thinking ... maybe not. Anybody?
UPDATE: The feature discussed below was finally added in C# 7.
The feature you want - to make managed local variable aliases is not supported in C#. You can do it with formal parameters - you can make a formal parameter that is an alias of any variable - but you cannot make a local which is an alias of any variable.
However, there is no technical difficulty stopping us from doing so; the CLR type system supports "ref local variables". (It also supports ref return types but does not support ref fields.)
A few years back I actually wrote a prototype version of C# which supported ref locals and ref return types, and it worked very nicely, so we have empirical evidence that we can do so successfully. However, it is highly unlikely that this feature will be added to C# any time soon, if ever. See http://ericlippert.com/2011/06/23/ref-returns-and-ref-locals/ for details.
I note that if I were you, I would avoid this in any language. Writing programs in which two variables share the same storage makes for code that is hard to read, hard to understand, hard to modify and hard to maintain.
See also the related question: Why doesn't C# support the return of references?
You can do it - or at least something very similar to what you want - but it's probably best to find another approach. For example, you can wrap the integers inside a simple reference type.
If you still want to do it, see the Ref<T> class posted by Eric Lippert here:
sealed class Ref<T>
{
private readonly Func<T> getter;
private readonly Action<T> setter;
public Ref(Func<T> getter, Action<T> setter)
{
this.getter = getter;
this.setter = setter;
}
public T Value { get { return getter(); } set { setter(value); } }
}
public class Program
{
public static void Main()
{
int flag=0,int1=0,int2=1;
Ref<int> iRef = (flag == 0 ?
new Ref<int>(() => int1, z => { int1 = z; }) :
new Ref<int>(() => int2, z => { int2 = z; }));
iRef.Value += 1;
Console.WriteLine(int1);
}
}
Output:
1
If all you need is to modify a value type within a function, then pass the parameter with the ref keyword.
int i = 0;
void increment(ref int integer)
{
integer++;
}
increment(ref i);
Yes you can do that with C# 7.0. It has support for returning references and storing references. See my answer here.
Fraid not. You could do it with unsafe code and pointers like so:
int flag=0,int1=0,int2=1;
unsafe
{
int *iRef = (flag==0? &int1:&int2);
*iRef +=1;
}
(not saying that's a good idea or anything :))
There is no direct equivelent in C#. There are a couple of options -
You can use unsafe code and pointers as suggested by dkackman.
Another alternative is to use a reference type (class) which holds the value. For exmaple:
// Using something like
public class Wrapped<T> {
public Wrapped(T initial) {
this.Value = initial;
}
public T Value { get; set; }
}
// You can do:
bool flag=false;
var int1 = new Wrapped<int>(0);
var int2 = new Wrapped<int>(1);
Wrapped<int> iRef = flag ? int2 : int1;
iRef.Value = iRef.Value + 1;
Since you're working with references to a class, the assignment to iRef copies the reference, and the above works...
You could use an Action delegate like this:
int flag = 0, int1 = 0, int2 = 0;
Action increment = flag == 0 ? (Action) (() => ++int1) : () => ++int2;
increment();