static int GetCount(BinTreeNode<int> L)
{
int count = 0;
while (L != null)
{
count++;
L = L.GetRight();
}
return count;
}
I have the method GetCount().
Now, BinTreeNode is a class that has the members: right, left and info.
for some reason, in the main function
static void Main(string[] args)
{
var t2 = new BinTreeNode<int>(null, 1, new BinTreeNode<int>(null, 2, new BinTreeNode<int>(null, 3, null)));
//Console.WriteLine(TreeLessThanTree(t1, t2));
Console.WriteLine(GetCount(t2));
Console.WriteLine(t2.GetInfo()); // this prints 1
Console.ReadKey();
}
This is weird, since in the function GetCount(), L (which is passed by reference) is changed to null.
Why wasn't t2 passed by reference? Why didn't t2 change?
The reference is passed by value. Meaning: the value of t2 is essentially just a pointer that happens to be the address of an object; when it is passed by value, the pointer (i.e. 4 or 8 bytes) is copied and passed in. It doesn't matter what the GetCount does with the local copy of the pointer: the change to the pointer is not observed at the call-site. However, if the method changes the object at the end of the pointer, then those changes will be observable.
The object is passed in the method. Every changes done in the properties of that object will be kept.
However, if you set something else to the local variable in the method, the original object won't be changed. If you want to change the variable, you have to explicitely use the ref keyword.
In example :
public class A
{
public string Foo { get; set; }
}
public class Program
{
// This is a local variable. If you set something else to this one, the original won't be changed
// |
// V
public static void DoSomething(A a)
{
a.Foo = "42"; // <---- This changes the property in the original
a = new A // <---- This sets something to the local variable a
{
Foo = "Hello world"
};
}
// This variable is passed by references. If you set something else to this one, the original will be changed
// | |
// V V
public static void DoSomethingElse(ref A a)
{
a.Foo = "42"; // <---- This changes the property in the original
a = new A // <---- This sets something to the original
{
Foo = "Hello world"
};
}
public static void Main()
{
var a = new A
{
Foo = "Bar"
};
DoSomething(a);
Console.WriteLine(a.Foo); // This outputs 42
// notice this --v
DoSomethingElse(ref a);
Console.WriteLine(a.Foo); // This outputs Hello world
}
}
Related
I'll try to resume everything as much as possible:
I have a class that creates a dictionary (let's call it secondary dictionary) with the initial values of some of the elements of another dictionary, (for simplicity, let's call it the main dictionary and this class does this only once) and then a thread that checks every x miliseconds against this main dictionary, that's being regularly updated every y miliseconds, for any changes on the elements that where stored in the initialization phase.
My problem is, that when I want to compare the values of element1 in the main dictionary against the value of element1 in the secondary dictionary, they're always the same, (I undersatnd that, until the main dictionary is nnot updated, both values will be the same, but when the main dictionary gets updated, so does the second, immediately, without me doing anything)
I've tried ConcurrentDictionaries, using locks, a combination of boths, creating a new element in the initialize functions instead of passing it directly, but nothing seems to work
class Checker
{
private static bool secondaryDictionaryHasChanged = false;
private static ConcurrentDictionary<int, ValueDTO> secondaryDictionary = new ConcurrentDictionary<int, ValueDTO>();
public Checker()
{
initSecondaryDictionary();
Thread checkChangedValsThread = new Thread(() => checkChangedValsThreadFunction(1000));
checkChangedValsThread.Start();
}
public void initSecondaryDictionary()
{
Object MainLock = new Object();
lock (MainLock)
{
Object secondaryLock = new Object();
lock (secondaryLock)
{
foreach (var variable in Maindictionary)
{
if (variable.isElegibleValue)
{
ValueDTO ValueDTOToAdd = new ValueDTO();
ValueDTOToAdd.EligibleVar = variable;
if (variable.contextVariables.Count > 0)
{
List<Var> contextVariablesToAdd = new List<Var>();
foreach (var item in variable.contextVariables)
{
contextVariablesToAdd.Add(getVarFromMainDictionary(item));
}
ValueDTOToAdd.ContextVars = contextVariablesToAdd;
}
secondaryDictionary.TryAdd(ValueDTOToAdd.EligibleVar.varCode, ValueDTOToAdd);
}
}
}
}
secondaryDictionaryHasChanged = false;
}
public void checkChangedValsThreadFunction(int checkTime)
{
while (true)
{
try
{
if (!secondaryDictionaryHasChanged)
{
Thread.Sleep(checkTime);
Object mainLock = new Object();
lock (mainLock)
{
Object secondaryLock = new Object();
lock (secondaryLock)
{
foreach (var item in secondaryDictionary)
{
ValueDTO secondaryDictionaryDTO = item.Value;
Var variableInSecondary = secondaryDictionaryDTO.EligibleVar;
Var variableInMain = getVarFromMainDictionary(item.Value.EligibleVar.varID);
int valueInMain = variableInMain.getIntValue();
int valueInSecondary = variableInSecondary.getIntValue();
if (valueInMain != valueInSecondary)
{
//IT NEVER ENTERS THIS HERE
}
}
}
}
}
}
catch (Exception e)
{
throw new Exception("Some exception: " + e.Message);
}
}
}
}
internal class ValueDTO
{
public Var EligibleVar { get; set; }
public List<Var> ContextVars { get; set; }
}
internal class Var
{
public int varCode { get; set; }
public string varID { get; set; }
}
I add a reduced version of the code I have the thing is that it will never go inside that if(mainValue != secondaryValue)
any help or info about where I'm going wrong will be deeply appreciated
As fildor already said, you have one object and two references to it.
To simplify your problem I created a short sample:
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
public class Example
{
class Person
{
public string Name
{
get;
set;
}
}
public static void Main()
{
var myPerson = new Person();
myPerson.Name = "User1";
var list1 = new List<Person>();
var list2 = new List<Person>();
// put a reference to myPerson into each of the lists
list1.Add(myPerson);
list2.Add(myPerson);
// get the reference to myPerson from list1
var myPersonInList1 = list1[0]
myPersonInList1.Name = "User2";
// this will print User2 because there is only one person object
Console.WriteLine(list2[0].Name);
}
}
Basically no matter where you pass the Person, it will always be a reference to the Person instance you created. All changes to it will apply to the object behind the reference. All references point to the same object.
A bit more in depth knowledge very simplified, but I hope you'll get the point:
There is a stack and a heap storage. The stack contains value types and references and the heap contains objects.
Stack:
Variable | Value
--------------------
myPerson | #abc123
list1[0] | #abc123
list2[0] | #abc123
myInt | 42
Heap:
Address | Value
-------------------
abc123 | { Name: "User2" }
Now every time you create a variable pointing to myPerson, you only create a new entry in the stack, pointing to the same object in the heap. Now, of course when you update the object behind the reference and set its name to "User1", all references will display the change.
I am creating an anonymous method and passing it into an action to be invoked later on. I would like to pass some numeric data (int) into my anonymous method. In order to pass the data by value, am I required to create copies? Or, will the data be passed by value?
Here is what I think the implementation would look like, if I had to create copies:
private void CreateAction()
{
int bus = 4;
CustomObject[] data = new object[16];
int length = 1500;
this.doWorkLater = new Action(() =>
{
var busCopy = bus;
var dataCopy = data;
var lengthCopy = length;
this.WorkMethod(busCopy, dataCopy, lengthCopy);
});
}
Is this (the above code) necessary in order to get length and bus by value?
In this case, will CustomObject[] data (some class I have created) be passed by reference or by value?
What you pass is not a By-Value Copy.
If you're not going to modify the values before executing the action, then you don't need to worry about how you pass the values. But no they are no passed by value. Even if you return the action and Invoke it from another method. the values are persisted in a class generated by the compiler. No need to worry about that
If you expect the data to change before executing the action then you're doing it wrong. The approach you're using (Copy a Value-Type to a local variable) should be done outside the action and not inside of it. As for the reference type (Array) even if you copy it to a local variable, the reference it copied so any change in the copy local variable is reflected.
private void CreateAction()
{
int bus = 4;
CustomObject[] data = new object[16];
int length = 1500;
var busCopy = bus; // a copy of bus
var dataCopy = data; // reference copy
var lengthCopy = length; // a copy of length
this.doWorkLater = new Action(() =>
{
this.WorkMethod(busCopy, dataCopy, lengthCopy);
});
bus = 10; // No effect on the action
length = 1700; // No effect on the action
this.doWorkLater();
}
This looks pointless, but you may sometimes need to copy a local variable to another local variable before passing it to an anonymous method. Check this Valid Example that fixes a reported unexpected behavior !
Closures capture values observably by reference* - note that code you have does not solve issue for general case, also if whole point of CreateAction is create one single action it will work.
private void CreateAction()
{
int bus = 4;
this.doWorkLater = new Action(() =>
{
var busCopy = bus;
this.WorkMethod(busCopy);
});
// if you change local `bus` before call to `doWorkLater` it will not work:
bus = 42;
doWorkLater(); // busCopy is 42.
}
* It actually collects all variables in a compiler created class and uses reference to it to access variables in a method and closure. Thus even value types look behave as if passed by reference.
This might help you to figure out what's going on.
If you start with this slightly simplified class:
public class Example
{
private void CreateAction()
{
int bus = 4;
object[] data = new object[16];
int length = 1500;
Action doWorkLater = () =>
{
var busCopy = bus;
var dataCopy = data;
var lengthCopy = length;
this.WorkMethod(busCopy, dataCopy, lengthCopy);
};
doWorkLater.Invoke();
}
public void WorkMethod(int bus, object[] data, int length)
{
}
}
...then the compiler produces basically this:
public class Example
{
private void CreateAction()
{
Example.GeneratedClass closure = new Example.GeneratedClass();
closure.parent = this;
closure.bus = 4;
closure.data = new object[16];
closure.length = 1500;
// ISSUE: method pointer
IntPtr method = __methodptr(closure.CreateAction);
new Action((object)closure, method)();
}
public void WorkMethod(int bus, object[] data, int length)
{
}
[CompilerGenerated]
private sealed class GeneratedClass
{
public int bus;
public object[] data;
public int length;
public Example parent;
internal void CreateAction()
{
this.parent.WorkMethod(this.bus, this.data, this.length);
}
}
}
The local variables trapped in the closure cease being local variables to the method and become public fields in the generate class.
Now everything that you know about C# and classes applies.
I have the following code. Is it possible to use reflection to get rid of the first two parameters since the information can be found in the Action assign (Or Expression), which will always have the form of b.P... = a.P...?
class A { .... }; var a = new A { P1 = .... } // class A and B are totally different clas
class B { .... }; var b = new B { P1 = .... } // But they have some properties with the same names
....
AssignAndDoSth(a.P1, b.P1, () => b.P1 = a.P1);
private void AssignAndDoSth<T>(T curr, T prev, Action assign) // assign can be Expression
{
if (!EqualityComparer<T>.Default.Equals(curr, prev))
{
assign();
Do(prev);
....
}
}
The short answer would be "I strongly advise against it"; in reality, this is actually an instance method of a compiler-generated capture class; so you would need to deconstruct the IL of the target method, and evaluate that IL against the fields of the target instance. Not good. What that actually looks like is something like:
var ctx = new SomeType();
ctx.a = new A { P1 = .... };
ctx.b = new B { P1 = .... };
AssignAndDoSth(a.P1, b.P1, new Action(ctx.SomeMethod));
...
class SomeType {
public A a;
public B b;
public void SomeMethod()
{
b.P1 = a.P1;
}
}
The other approach would be to refactor to an Expression<Action> - but that doesn't change the work involved much - it just presents a more friendly API (relatively speaking).
Either way, all that inspection will have a non-trivial performance cost.
An expression tree may not contain an assignment operator, but can contain operator ==
static void AssignAndDoSomething<T>(T curr, T prev, Expression<Func<bool>> assign)
{
var logExpr = assign.Body as System.Linq.Expressions.BinaryExpression;
//output rid of the first parameter
Console.WriteLine(logExpr.Left);
//output rid of the second parameter
Console.WriteLine(logExpr.Right);
//assign first parameter
Expression.Lambda<Action>(Expression.Assign(logExpr.Left, Expression.Constant(curr))).Compile()();
//assign second parameter
Expression.Lambda<Action>(Expression.Assign(logExpr.Right, Expression.Constant(prev))).Compile()();
}
class A
{
public int P1;
}
class B
{
public int P1;
}
var a = new A();
var b = new B();
AssignAndDoSomething(a.P1, b.P1, () => b.P1 == a.P1);
I am trying to pass an array to a method. The array contains objects which need to be nulled. The method would simply null each object in a loop. I need this to reflect back in the caller.
Sample code (code goodness & minor syntactical issues can be ignored):
public class ABC
{
...
}
private void SomeMethod()
{
var toBeNulledObj1 = new ABC();
var toBeNulledObj2 = new ABC();
var arrayOfNullableObjects = new ABC[]{toBeNulledObj1 ,toBeNulledObj2};
NullingFunction(arrayOfNullableObjects);
}
private void NullingFunction(ABC[] arrayOfNullableObjects)
{
for(int i = 0; i< arrayOfNullableObjects.Length ; i++)
{
arrayOfNullableObjects[i] = null;
}
}
Clearly upon returning, toBeNulledObj1 & toBeNulledObj2 are not null but retain their older values though arrayOfNullableObjects now has two null objects. I realise that ref & out only apply to the collection parameter (here, arrayOfNullableObjects which doesn't even need a ref). I tried passing them in as params instead of a collection but that doesn't help, either (ref & params cannot be combined).
Question: How can I alter each/any object in a collection of objects within a method such that the change is visible to the caller? I am not altering the collection itself. Please note, I am not changing the contents/members of toBeNulledObj1 but the reference itself (to either null or a new object).
Solution #1: Unsafe code
One solution is using a unsafe code. You have to think twice before using it, and I do not know if you will be happy with my answer, but here it is.
static private void SomeMethod()
{
ABC toBeNulledObj1 = new ABC();
ABC toBeNulledObj2 = new ABC();
IntPtr[] arrayOfNullableObjects = new IntPtr[] { MakeReference(ref toBeNulledObj1), MakeReference(ref toBeNulledObj2) };
NullingFunction(arrayOfNullableObjects);
}
static private void NullingFunction(IntPtr[] arrayOfNullableObjects)
{
foreach (IntPtr reference in arrayOfNullableObjects)
ClearReference(reference);
}
/// <summary>
/// Makes the reference to the reference value of a reference type.
/// </summary>
static unsafe private IntPtr MakeReference<T>(ref T value)
where T: class
{
TypedReference reference = __makeref(value);
return *(IntPtr*)&reference;
}
/// <summary>
/// Clears the reference to a reference type, using a reference to that reference value.
/// </summary>
static unsafe private void ClearReference(IntPtr reference)
{
if (sizeof(IntPtr) == 4)
*((int*)reference) = 0;
else
*((long*)reference) = 0;
}
Solution #2: Anonymous class
The second solution could be done by using an anonymous class which holds your data. The fields inside this anonymous class are cleared. A disadvantage is that you have a second class and the reference to this class also should to be cleared. (This can be done by adding ref to o and in the NullingFunction set o to null.) Of course you can also use a predefined class, but his solution is the closest to your code in your OP.
public static void SomeMethod()
{
var container = new
{
toBeNulledObj1 = new ABC(),
toBeNulledObj2 = new ABC(),
};
NullingFunction(container);
}
private static void NullingFunction<T>(T container)
where T : class
{
if (container == null)
return;
foreach(FieldInfo f in container.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic))
if (f.FieldType.IsClass)
f.SetValue(container, null);
}
When you say you want to set them to null, do you mean that you want to destroy the object?
C# has automatic garbage collection, so as soon as an object goes out of scope (that is, when no other objects make reference to it), the garbage collector will destroy it.
In the code above, the label "tobeNulledObj1" still refers to an object, and your array also points to it before you call the NullingFunction.
After you call the NullingFunction, you still have one reference pointing to the object (that is, tobeNulledObj1). If you set tobeNulledObj1 to null, then the Garbage Collector will collect it.
EDIT: I second cheedep's question - what is it exactly that you are trying to do? What do you want your variables to hold at the end?
If function A holds a reference to a variable i.e:
var toBeNulledObj1 = new ABC();
var toBeNulledObj2 = new ABC();
And does not pass this into function B:
private NullingFunction(ABC[] arrayOfNullableObjects)
Then there is nothing that function B can do to change the reference that toBeNulledObj1 / 2 points to.
Since ref is not allowed along with params (as you mentioned):
private void NullingFunction(ref params ABC[] arrayOfNullableObjects)
{
for (int i = 0; i < arrayOfNullableObjects.Length; i++)
{
arrayOfNullableObjects[i] = null;
}
}
The available alternative is to create overloads e.g.:
private void SomeMethod()
{
var toBeNulledObj1 = new ABC();
var toBeNulledObj2 = new ABC();
NullingFunction(ref toBeNulledObj1, ref toBeNulledObj2);
Console.ReadKey();
}
private void NullingFunction(ref ABC one)
{
one = null;
}
private void NullingFunction(ref ABC one, ref ABC two)
{
one = null;
two = null;
}
Is wrapping acceptable?
class Wrapped<T> where T : new() {
private T val = new T();
...
public void Nullify() { val = null; }
}
private void SomeMethod()
{
var toBeNulledObj1 = new Wrapped<ABC>();
var toBeNulledObj2 = new Wrapped<ABC>();
var arrayOfNullableObjects = new Wrapped<ABC>[]{toBeNulledObj1 ,toBeNulledObj2};
NullingFunction(arrayOfNullableObjects);
Debug.Assert(toBeNulledObj1.Get() == null);
// Or...
Debug.Assert(toBeNulledObj1.IsDefined == false);
// Or...
Debug.Assert(toBeNulledObj1.IsNull == true);
}
private void NullingFunction(Wrapped<ABC>[] arrayOfNullableObjects)
{
for(int i = 0; i< arrayOfNullableObjects.Length ; i++)
{
arrayOfNullableObjects[i].Nullify();
}
}
(Disclaimer: hand-compiled code :) may contain errors)
If you need it as a general pattern, you can make NullingFunction parametric (T, U), with a constaint where U: Wrapped<T>
The idea is to make something similar to Nullable for ref types, or something that looks like a smart pointer, if you are familiar with C++.
Thus, wrapper could have T Get() (or an implicit conversion to T) to get out the value, an IsDefined property, and so on.
I'm making a graphic control class Info which should display some text on screen. The text is some object's string. I'd like to be able to get that object's latest value from within an instance of Info class.
class Info
{
public string Text;
}
void Program()
{
ClassA obj = new ClassA();
obj.name = "Instance of ClassA";
Info wind1 = new Info();
wind1.Text = obj.name; // this just copies current value, but should be a reference or something
/* obj.name value changes several times before it's time to display it again */
// Info window drawing method
foreach (var item in Windows) // Windows is List<Info>
Draw(item.Text); // this doesn't get the latest value
}
How should I change the code so I can get the latest string value from within the drawing section?
Update: If you need something that'll work for any type, you'll have to use delegates. For example:
class Info
{
private Func<string> getText;
public Info(Func<string> getText)
{
getText = getText;
}
public string Text
{
get
{
return getText();
}
}
}
void Program
{
ClassA obj = new ClassA();
obj.name = "Instance of ClassA";
Info wind1 = new Info(() => obj.name);
// Now do your stuff.
}
In this case, Info is given an anonymous function that returns a string. When you access its Text property, the function is evaluated to retrieve that string. How the string is retrieved, and where it comes from, is determined by the client code (i.e. the Program method). This way, Info doesn't rely on any particular type.
You could pass the ClassA object into your Info instance, so that it can get the value of.name itself.
Something like this, perhaps?
class Info
{
public Info(ClassA obj)
{
TheObject = obj;
}
public ClassA TheObject
{
get;
set;
}
public string Text
{
get
{
return TheObject.name;
}
}
}
void Program
{
ClassA obj = new ClassA();
obj.name = "Instance of ClassA";
Info wind1 = new Info(obj);
// Now do your stuff.
}