How to overwrite a point in memory in c#? - c#

I want to do have the following functionality:
var item0 = new Item();
var item1 = item0;
item0 = null;
Console.WriteLine(item1 == null); // true
So I'd be overwriting the memory that item0 and item1 point to.
I figured maybe I could do this with pointers..? However, when I tried declaring an item pointer:
Item* itemPointer;
i got an error. Any ideas?

Since C# 7 You can use Ref Locals:
var item0 = new Item();
ref var item1 = ref item0;
item0 = null;
Console.WriteLine(item1 == null); // true
// THIS WORKS!
Ref returns and ref locals have mainly been introduced to avoid copying large structs in time sensitive scenarios like gaming where large arrays of vectors have to be processed. I don't see the advantage in using them with reference types. They tend to make the code hard to understand, thus I would restrict their use to exceptional and rare cases.

var item0
{
get{return item0;}
set
{
item0 = value;
item1 = item0;
}
}
Something like this will overwrite the value of item1 every time the value of item0 changes.

There are no local aliases/references in C#
However there is a ref keyword for arguments:
static void RefClean(ref String arg){
arg = null;
}
static void Main(string[] args)
{
var test = "Hello";
Console.WriteLine(test == null);
RefClean(ref test);
Console.WriteLine(test == null);
}
For pointers you need the unsafe keyword, and you have to use unmanaged types only (primitive types and structures built from them), which rules out your case with objects/references. See https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/unsafe-code-pointers/pointer-types for some overview.

Related

Why the tuple-type list element's value cannot be modified?

In C# 8.0, I can modify the value inside a tuple directly by accessing the field name:
(string name, int score) student = ("Tom", 100);
student.name = "Jack";
Console.WriteLine(student);
And I can modify the list element's property as follow:
var list = new List<Student>(); // assume I have a Student class which has a Name property
list.Add(new Student { Name = "Tom" });
list[0].Name = "Jack";
Console.WriteLine(list[0]);
But why can't I modify the tuple-type element's value like this?
var list = new List<(string name, int score)>();
list.Add(("Tom", 100));
list[0].name = "Jack"; // Error!
Console.WriteLine(list[0]);
A tuple (ValueTuple) is a struct. Rather than returning a reference to the value as is the case with your Student example, you would actually recieve a copy of the tuple.
Changes to that copy wouldn't be reflected in the list and would be discarded. The compiler is smart enough to recognize this and stops you from doing it.
If it did compile, it would be to something similar to the following:
var list = new List<(string name, int score)>(); list.Add(("Tom", 100));
var copy = list[0];
copy.name = "Jack";
Console.WriteLine(copy.name); // Jack
Console.WriteLine(list[0].name); // still Tom
Mutable structs can be dangerous if you don't use them properly. The compiler is simply doing its job.
You can work around this with the following:
var list = new List<(string name, int score)>(); list.Add(("Tom", 100));
var copy = list[0];
copy.name = "Jack";
list[0] = copy; // put it back
Console.WriteLine(copy.name); // Jack
Console.WriteLine(list[0].name); // Jack
Try It Online
If you use an array (string, int)[] instead of a List<(string, int)>, this isn't a problem due to the way array element access works:
var arr = new (string name, int score) [] { ( "Tom", 10 ) };
arr[0].name = "Jack";
Console.WriteLine(arr[0].name); // Jack
Try It Online
This behavior is not unique to List or your tuple type. You'll experience this issue with any collection where the element is a Value Type (unless of course they offer a ref element accessor).
Note that there are similar issues when having a readonly field of a mutable value type that mutates via method calls. This can be much more insidious as no error or warning is emitted:
struct MutableStruct {
public int Val;
public void Mutate(int newVal) {
Val = newVal;
}
}
class Test {
private readonly MutableStruct msReadonly;
private MutableStruct msNormal;
public Test() {
msNormal = msReadonly = new MutableStruct(){ Val=5 };
}
public void MutateReadonly() {
Console.WriteLine(msReadonly.Val); // 5
msReadonly.Mutate(66); // defensive copy!
Console.WriteLine(msReadonly.Val); // still 5!!!
}
public void MutateNormal() {
Console.WriteLine(msNormal.Val); // 5
msNormal.Mutate(66);
Console.WriteLine(msNormal.Val); // 66
}
}
new Test().MutateReadonly();
new Test().MutateNormal();
Try It Online
ValueTuple is a great addition to the framework and language. But there's a reason you'll often hear that [Mutable] structs are evil. In the majority of cases you shouldn't hit these restrictions. If you find yourself falling into this pattern a lot, I suggest moving over to a record, which is a reference type (thus not suffering these issues) and can be reduced to a tuple-like syntax.
Mutable value types are evil, it's hard to see why this prints "Tom" not "Jack":
(string name, int score) student = ("Tom", 100);
(string name, int score) student2 = student;
student.name = "Jack";
Console.WriteLine(student2);
The reason is that you always create a copy. Because it's not obvious you should avoid mutable value types. To avoid that people will fall into that trap the compiler just allows to modify the object directly via properties(like above). But if you try to do it via a method call you get a compiler error "Cannot modify the return value of ... because it is not a variable".
So this is not allowed:
list[0].name = "Jack";
It would create a new copy of the ValueTuple, assigns a value but doesn't use or store it anywhere.
This compiles because you assign it to a new variable and modify it via property:
(string name, int score) x = list[0];
x.name = "Jack"; // Compiles
So it compiles but gives you again a suprising result:
Console.WriteLine(list[0]); // Tom
Read more about it here: Do Not Define Mutable Value Types

Alternative to using ref in foreach?

I have a modifying method with a signature like
private bool Modify(ref MyClass obj);
that will make modifications to obj and indicate succes with it's return value. Modify is not reassigning the reference (I know that this wouldn't work), just modifying instance fields, so I want to use it to do something like the following:
foreach(MyClass obj in myList)
{
bool success = Modify(obj);
// do things depending on success
}
I am running into a problem compiling as obj is "not being passed with the ref keyword". However, if I put the ref keyword in like so:
bool success = Modify(ref obj);
I get "cannot use obj as a ref/out because it is a 'foreach iteration variable". I understand that foreach uses an immutable iterator and that's why this doesn't work.
My question is what is the easiest alternative to make something like this work?
I have tried using
foreach(int i = 0; i < myList.Count; i++)
{
bool success = Modify(ref myList[i]);
// do things depending on success
}
but they I get "a property or indexer may not be passed as an out of ref parameter".
Thanks your help.
Any type within C# is passed actually by value. When you pass an instance of a class to a method what is actually passed is not the instance itself but a reference to it which itself is passed by value. So effectivly you're passing instances of a class as reference - which is why you call them reference-types.
In your case you just modify an existing instance referenced by that reference-value in your method, no need to use the ref-keyword.
foreach(var m in myList)
{
MyMethod(m);
}
MyMethod(MyClass instance)
{
instance.MyProperty = ...
}
If you'd really pass the reference by reference you'd re-assign the obj on every iteration within your loop which isn't allowed within a foreach-block. This would be similar to the following:
foreach(var m in myList)
{
m = new MyClass();
}
On the other side you could also use a classic for-loop. However you'd need a temporary variable to store the outcome of your method:
for(int i = 0; i < myList.Length; i++)
{
var tmp = myList[i];
MyMethod(ref tmp);
myList[i] = tmp;
}
You state
Modify is not reassigning the reference
Therefore, there is no reason the Modify(ref MyClass) function needs to pass argument by ref.
You should be able to do the same "modifications", whatever that is (please clarify that) by passing the object reference by value, i.e. removing the ref keyword.
So, the fix here should be changing your Modify function signature from Modify(ref MyClass) to Modify(MyClass)
use a temp variable to bypass the message
foreach(MyClass obj in myList)
{
MyClass objTemp = obj;
bool success = Modify(ref objTemp);
// do things depending on success
}
private MyMethod(ref MyClass instance)
{
instance.MyProperty = ...
}
It is solved by using LINQ.
My Code:
private static List<string> _test = new List<string>();
public List<string> Test { get => _test; set => _test = value; }
static void Main(string[] args)
{
string numString = "abcd";
_test.Add("ABcd");
_test.Add("bsgd");
string result = _test.Where(a => a.ToUpper().Equals(numString.ToUpper()) == true).FirstOrDefault();
Console.WriteLine(result + " linq");
}
You need to cast your array to a Span:
int[] nums = new[] { 1, 2, 3, 4, 5 };
int i = 0;
foreach (ref var item in nums.AsSpan())
{
item += 10;
Console.WriteLine(nums[i++]);
}
output:
11
12
13
14
15
You can modify the iteration variable because Span Enumerator's Current property is of ref T type.

efficient way to check for changes in a "calculation" class

I have the following "calculation" class.
public class Foo
{
private int? _sum = 0;
public int Sum
{
get
{
if (_sum == null)
_sum = 1 + 1; //simple code to show "some" calculation happens...
return _sum.GetValueOrDefault();
}
}
}
In this example there is only 1 Field/Member but in my real class there are around 50 Members, that all look similar just with different value calculations.
In the class I also have a Recalc method.
This Recalc method does 4 things
Save the old values
set all fields to null
calls the getter of every member
Checks if the old values differ from the newvalues and does related stuff
I am not sure whats the best way to store the old values and check for changes with the new values.
My current implementation is this:
public string GetValuesKey()
{
//again this method only handles the 1 Member and not all 50 in real app its string.Format("{0}|{1}|{2}|...{49}|{50}|", ....);
return string.Format("{0}|", this.Sum);
}
public void Recalc()
{
var oldValues = GetValuesKey();
//set all fields to null
//call the getters
var newValues = GetValuesKey();
if (oldValues != newValues)
{
//something changed...
}
}
But with this code there is a memory/performance issue since I am doing boxing with the struct (decimal) writing to a reference type (string).
I kind of want to prevent doing 50 additional fields (something like _oldSum) for all the members.
I just need to check if any member has changed during the Recalc procedure.
Just in Case, I cannot do the following code.
public void Recalc()
{
var changes = false;
var oldValue = this.Sum;
_sum = null;
var newValue = this.Sum;
if (oldValue != newValue)
changes = true;
//check next member
oldValue = this.Sum2;
_sum2 = null;
newValue = this.Sum2;
if (oldValue != newValue)
changes = true;
//check next member and so on...
}
Since I need to set all fields to null first and only AFTER all of them have been set to null I can execute the getters, since the members are dependant on each other for exmple if the Sum Member would aggregate two other members and they havent been set to null first they would still have old values.
So I need a way to store something that represents all values before setting the fields null and after calling the getter of the members a way to check for changes.
Any help is welcome.
Edit:
Here is the code, I wrote to test performance/memory:
http://pastebin.com/3WiNJHyS
Instead of combining all values in a string and have some pefomance hit on that string construction - put all values in array (of decimal), then set all fields to null, make your calculation and compare arrays of old and new values.
If you don't want to write yourself all the 50 _oldValue fields, the only alternative is to use Reflection, that implies some boxing/unboxing, so performance will not be the best possible.
Anyway, in the following implementation I assume that in the Foo class the members that are involved in the calculation are all and the only ones that are properties of type decimal?.
Otherwise, we need a more complicated solution, with BindingFlags, and/or Attribute on every field/property involved, and so on.
public void Recalc()
{
var propertyInfos = GetType()
.GetProperties()
.Where(pInfo => pInfo.PropertyType.IsValueType);
var fieldInfos = GetType()
.GetFields()
.Where(fInfo => fInfo.FieldType.IsValueType);
//create a dictionary with all the old values
//obtained from the backing fields.
var oldValueDictionary = fieldInfos.ToDictionary(
fInfo => fInfo.Name,
fInfo => (decimal?)fInfo.GetValue(this));
//set all properties to null
foreach (var pInfo in propertyInfos)
pInfo.SetValue(this, null);
//call all the getters to calculate the new values
foreach (var pInfo in propertyInfos)
pInfo.GetValue(this);
//compare new field values with the old ones stored in the dictionary;
//if only one different is found, the if is entered.
if (fieldInfos.Any(fInfo =>
(decimal?)fInfo.GetValue(this) != oldValueDictionary[fInfo.Name]))
{
//do stuffs
}
}
As a final note, your class configuration is very strange. Are you sure that setting all the calculations in the getters is the best choice? Maybe you should re-think about you design. One task is to retrieve a property value (a getter), another task is to calculate something (starting from some value stored in the backing fields)...

Atomically reading values of fields via reflection

Let's suppose I have the following C# declaration:
struct Counters
{
public long a;
public long b;
public long c;
}
Is this possible to iterate through the fields of a given instance of Counters and read their values using Interlocked.Read()? I.e.
Counters counters;
foreach (var counter in typeof(Counters).GetFields())
{
var value = Interlocked.Read(???);
}
You can't use Interlocked.Read directly, because it requires a ref argument - and you can't use the required System.Int64& type directly.
So, back to reflection:
// You can keep this static in some helper class
var method = typeof(Interlocked).GetMethod("Read", new []{ typeof(long).MakeByRefType() });
var result = (long)method.Invoke(null, new object[] { counter.GetValue(instance) });
EDIT: This doesn't work either, I botched up my testing. You're still reading a copy that wasn't produced atomically.
This will work, though:
public delegate long AtomicReadDelegate<T>(ref T instance);
public static AtomicReadDelegate<T> AtomicRead<T>(string name)
{
var dm = new DynamicMethod(typeof(T).Name + "``" + name + "``AtomicRead", typeof(long),
new [] { typeof(T).MakeByRefType() }, true);
var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldflda, typeof(T).GetField(name));
il.Emit(OpCodes.Call,
typeof(Interlocked).GetMethod("Read", new [] { typeof(long).MakeByRefType() }));
il.Emit(OpCodes.Ret);
return (AtomicReadDelegate<T>)dm.CreateDelegate(typeof(AtomicReadDelegate<T>));
}
private readonly AtomicReadDelegate<Counters>[] _allTheReads =
new []
{
AtomicRead<Counters>("a"),
AtomicRead<Counters>("b"),
AtomicRead<Counters>("c")
};
public static void SomeTest(ref Counters counters)
{
foreach (var fieldRead in _allTheReads)
{
var value = fieldRead(ref counters);
Console.WriteLine(value);
}
}
You might want to cache the delegates you get from AtomicRead - they can be reused safely. A simple concurrent dictionary will work just fine.
Don't forget that this only supports longs; you'll need to use Interlocked.CompareExchange if you need to atomically read other types as well (apart from references and ints, of course - though depending on your code, you might need some memory barriers even in that case).
Values for instance fields are per object, so you need to take the value for a particular object.
Counters counter1 = new Counter() { a = 40; b = 50; c = 60; }
Type counterType = counter1.GetType();
foreach (var field in counterType.GetFields())
{
var value = Interlocked.Read(field.GetValue(counter1));
}
In this case we get values for the fields of counter1 and not any other struct instance.
If you really need an atomic long, then it's better to use atomics.net library (which is available via NuGet).
If you need just read values of struct passed in your thread, then it's safe to read, since it's passed by value. But if it's passed by reference or if you work with unsafe/native code, then it's better to say what exactly you want to achieve.

Return value, Ref, Out is there any difference? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am doing this,
public Order Add(Order order)
{
order.thisA = GetValue1();
// update the state of object
return order;
}
Would i be any beneficial if I use Ref or Out here instead ?
Further implementation would require me to add this method,
public Order[] UpdateCollection(Order[] orderCollection)
{
foreach(Order o in orderCollection)
o = Update(o);
return orderCollection;
}
Please tell me in light of best practices as well.
Context:
At the moment I am only returning INT id of the order but in future maybe I need to return more properties, but here is the full context,
https://codereview.stackexchange.com/questions/97778/crud-operation-class#
In this case:
public MyObject Update(MyObject object)
{
object.thisA = GetValue1();
// update state of object
return object;
}
You are not changing MyObjects reference so:
You don't need to return the object back.
You don't need to use ref.
You don't need to use out.
Using out is for initializing an object (You must assign a value in the function).
MyObject obj; // didn't assign anything
Method(out obj);
public void Method(out MyObject obj){
obj = new MyObject(); // assigned
}
using ref is in case you might change the reference of the object inside the method:
MyObject obj = new MyObject();
Update(ref obj);
public void Update(ref MyObject obj)
{
obj = new MyObject(); // changing the ref!!!
obj.thisA = GetValue1();
}
BTW, in your case you don't need to do anything:
public void UpdateCollection(Order[] orderCollection)
{
foreach(Order o in orderCollection)
Update(o);
}
public void Update(MyObject object)
{
object.thisA = GetValue1();
}
You are foreaching an array and updating the object and not the reference.
You use ref if there is a chance that you want to change the reference instead of the object's data.
Example:
public void RetargetReference(ref List<string> originalList)
{
originalList = new List<string>();
originalList.Add("World");
}
List<string> inList = new List<string>();
inList.Add("Hello");
RetargetReference(ref inList);
This will change the reference of inList. It will now point to a new list which contains one entry "World". The list that contained "Hello" will no longer be available to you unless you have another reference to it.
ref parameters can be useful if you want to change parameter you passed in during the execution of the method.
out will be used to have the method create a new object instance without you being able to pass a value in!
Example:
public void CreateReference(out List<string> newList)
{
newList = new List<string>();
newList.Add("Hello World");
}
List<string> list;
CreateReference(out list);
After that, list will point to a new List<string> instance. Inside the method you have no access to whatever newList actually "points to". You will always have to create a new instance.
out parameters can be useful if you want your method to return more than one result. For example, the following method would return a bool to indicate success and two out parameters that contain the data:
public bool TrySplitString(string source, out string part1, out string part2)
{
part1 = String.Empty;
part2 = String.Empty;
string[] parts = source.Split('=');
if (parts.Length != 2)
return false;
part1 = parts[0];
part2 = parts[1];
return true;
}
Objects are generally passed by reference in C#, so the following method actually changes the data "outside" the method:
public void ChangeList(List<string> list)
{
list.Add("World");
}
List<string> inList = new List<string>();
inList.Add("Hello");
ChangeList(inList);
After that, inList contains two entries: "Hello" and "World".
The reason why sometimes you return the object that was passed in as a parameter is that this allows so called "method chaining" where you can "write sentences" instead of "commands". You'll see that in my next example:
public static List<string> CreateList()
{
return new List<string>();
}
public static List<string> AddItem(this List<string> list, string item)
{
list.Add(item);
return list;
}
public static List<string> DoSomethingWithList(this List<string> list)
{
...;
return list;
}
You can use this code and write something like this:
List<string> list = CreateList().AddItem("Hello").DoSomethingWithList();
Return object back may be used for create "method chaining", like this:
someObject.Update(MyObject object).MyObjectMethod1().MyObjectMethod2();
I can't really workout what you really trying to achieve. However, i will give you some basics.
In C#, arguments can be passed to parameters either by value or by reference.
If your MyObject is a reference type (eg: class) then it is passed to function as reference and hence you will end up in modifying same object. In other way, any change you make on this instance (within the function) will have a direct impact on that instance and it will continue to be true in the current execution environment.
On the other hand, if MyObject is a value type (eg: struct) then a copy of it will be passed to method. That is, original instance of your value type is not altered even if you modify the members within the method. This is default behavior when it comes to value type.
Now assume a scenario where you wanted to modify the original instance of value type. This can be achieved only if you pass the reference of your value type. Here comes ref and out. Using these keyword, you can pass parameter by reference. There are differences between ref and out, which can be learned separately. However, keeping your context in mind, the ref and out both allow the called method to modify a parameter.
ref means that the parameter has a value on it before going into the function. So that the function can read and or change the value within it. On the other hand, out means that the parameter has no official value before going into the function. The called function must initialize it before parameter goes out from function.

Categories