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();
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.
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;
I am working on a C++ CLI wrapper for a C API. The C API has a structure that contains an array of four unsigned shorts and an array of four ints. So I have created a similar class for the C# code to use when calling into the wrapper function.
// C Structure
typedef struct c_Struct_
{
unsigned short uShorts[4];
int ints[4];
} c_Struct;
// C++ CLI Class
public ref class CliClass
{
public:
property array<unsigned short>^ UnsignedShorts
{
array<unsigned short>^ get()
{
return _unsignedShorts;
}
}
property array<int>^ Ints
{
array<int>^ get()
{
return _ints;
}
}
CliClass(array<unsigned short>^ us, array<int> i)
{
_unsignedShorts = us;
_ints = i;
}
private:
array<unsigned short>^ _unsignedShorts;
array<int>^ _ints;
}
Now we come to my question. I have added an internal method to the the CLI class to create a struct:
internal:
c_Struct ToStruct()
{
c_Struct results;
results.uShorts[0] = UnsignedShorts[0];
results.uShorts[1] = UnsignedShorts[1];
results.uShorts[2] = UnsignedShorts[2];
results.uShorts[3] = UnsignedShorts[3];
results.ints[0] = Ints[0];
results.ints[1] = Ints[1];
results.ints[2] = Ints[2];
results.ints[3] = Ints[3];
return results;
}
but I get the error: IntelliSense: a value of type "System::Object ^" cannot be assigned to an entity of type "unsigned short" for each assignment. What is the proper syntax for this?
Unboxing the reference type first, try this:
results.uShorts[0] = (unsigned short)UnsignedShorts[0];
The code is correct, you'll see that your program compiles just fine. Nothing is being boxed. This is a bug in the IntelliSense parser. A rather strange one, hard to imagine how it fumbles this. Not entirely uncommon, the parser was made by another company. The Edison Design Group, pretty famous for writing the only compiler that was ever able to implement the C++03 standard correctly. C++/CLI gives them heartburn though.
Two basic workarounds, you could use the field instead of the property:
c_Struct ToStruct() {
c_Struct results;
results.uShorts[0] = _unsignedShorts[0];
// etc...
}
But that doesn't fix a problem you'd have with code that uses the class. You could make them indexed properties instead:
property unsigned short UnsignedShorts[int]
{
unsigned short get(int index) {
return _unsignedShorts[index];
}
}
// Same for the Ints property.
Another work-around is to assign to a temporary local variable first.
array<int> ^temp = ArrayOfIntsProperty;
int j = temp[0];
This only affects properties - it appears that functions returning managed arrays work as expected when the call is indexed.
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.
I read this post about card shuffling and in many shuffling and sorting algorithms you need to swap two items in a list or array. But what does a good and efficient Swap method look like?
Let's say for a T[] and for a List<T>. How would you best implement a method that swaps two items in those two?
Swap(ref cards[i], ref cards[n]); // How is Swap implemented?
Well, the code you have posted (ref cards[n]) can only work with an array (not a list) - but you would use simply (where foo and bar are the two values):
static void Swap(ref int foo, ref int bar) {
int tmp = foo;
foo = bar;
bar = tmp;
}
Or possibly (if you want atomic):
Interlocked.Exchange(ref foo, ref bar);
Personally, I don't think I'd bother with a swap method, though - just do it directly; this means that you can use (either for a list or for an array):
int tmp = cards[n];
cards[n] = cards[i];
cards[i] = tmp;
If you really wanted to write a swap method that worked on either a list or an array, you'd have to do something like:
static void Swap(IList<int> list, int indexA, int indexB)
{
int tmp = list[indexA];
list[indexA] = list[indexB];
list[indexB] = tmp;
}
(it would be trivial to make this generic) - however, the original "inline" version (i.e. not a method) working on an array will be faster.
11 years later and we have tuples...
(foo, bar) = (bar, foo);
A good swap is one where you don't swap the contents. In C/C++ this would be akin to swapping pointers instead of swapping the contents. This style of swapping is fast and comes with some exception guarantee. Unfortunately, my C# is too rusty to allow me to put it in code. For simple data types, this style doesn't give you much. But once you are used to, and have to deal with larger (and more complicated) objects, it can save your life.
What about this?
It's a generic implementation of a swap method. The Jit will create a compiled version ONLY for you closed types so you don't have to worry about perfomances!
/// <summary>
/// Swap two elements
/// Generic implementation by LMF
/// </summary>
public static void Swap<T>(ref T itemLeft, ref T itemRight) {
T dummyItem = itemRight;
itemLeft = itemRight;
itemRight = dummyItem;
}
HTH
Lorenzo
Use:
void swap(int &a, int &b)
{
// &a != &b
// a == b OK
a ^= b;
b ^= a;
a ^= b;
return;
}
I did not realize I was in the C# section. This is C++ code, but it should have the same basic idea. I believe ^ is XOR in C# as well. It looks like instead of & you may need "ref"(?). I am not sure.
You can now use tuples to accomplish this swap without having to manually declare a temporary variable:
static void Swap<T>(ref T foo, ref T bar)
{
(foo, bar) = (bar, foo)
}
For anyone wondering, swapping can also be done also with Extension methods (.NET 3.0 and newer).
In general there seems not to be possibility to say that extension methods "this" value is ref, so you need to return it and override the old value.
public static class GeneralExtensions {
public static T SwapWith<T>(this T current, ref T other) {
T tmpOther = other;
other = current;
return tmpOther;
}
}
This extension method can be then used like this:
int val1 = 10;
int val2 = 20;
val1 = val1.SwapWith(ref val2);