C# and storing reference to method parameter - c#

For a little background information, I've got an application that's running in a loop, and over ever tick it calls a method Tick. There's a bunch of classes that extend a base class and all have their own tick methods, and get added to a dependency chain so that say when class A gets called and it's chain has instances of B and C in it, B.Tick gets called, followed by C.Tick, and then finally A.Tick.
So in pseudo code my class kind of looks like this:
public class A : Super
Super b;
Super c;
ArrayList one;
ArrayList two;
tick(){
one.Add(b.LastValue);
two.Add(c.LastValue);
... do something with one and two ...
}
A(){
b = new B(some other array list);
c = new C(ref one);
}
B is working fine, and always gets the correct value. The problem is I guess you can't store a reference to another variable in a class, so when I do new C(ref one); and the contructor for C is setting a class variable to one, later on after one is updated in A it's like C no longer knows that its still supposed to be pointing towards one (which is now updated) and is just empty (like it originally was inside the constructor). Any idea on how to achieve what I'm looking to do, without having to use C# pointers and unsafe code? Thanks, hopefully it makes sense :)
Edit:
Apparently people can't answer questions with confusing pseudo code that is completely unrelated to the actual question, so changed extends to :
Edit 2: C class
...
ArrayList local;
...
C(ref ArrayList one){
local = one;
}
Tick(){
LastValue = local[0] + 5; //not actual formula, just shows trying to use a referenced variable
}

Since one is an ArrayList, you can only pass it as a reference. You are now apparently passing it as a reference-to-a-reference to the constructor. You may not need that ref.
But please show a more complete idea of what you are trying to accomplish.
Edit:
After seeing your C class, there is no need for the ref. c will share the instance of the ArrayList that A calls one.
This seems to boil down to the general referencetype/valuetype issue in .NET. To summarize:
instances of objects do not have a name and cannot (physically) be passed as parameter at all.
you always access an instance through a reference. In your code, one (2x) , two, local are all references to Arraylist instances.
the references themselves behave like valuetypes, ie assignment means copying.
To learn more about referencetypes/valuetypes, search for 'copy semantics' and avoid postings that start with 'valuetypes exist on the stack'.

There's nothing to prevent you from doing this. Whether or not it's a good idea is another question though. In general, I'd recommend trying to avoid changing state between method calls if you can avoid it. Of course, the key expression there is "if you can avoid it". :-)

you can't store a reference to another variable in a class
You can, people do it all the time. Simply assign it to a (private) field.
so when I do new C(ref one); [snip /] later on after one is updated in A it's like C no longer knows that its still supposed to be pointing towards one
Actually, it does know that, but you should assign one to a member field. Assigning to objects is nothing more then setting a reference to the object. Changing the object, changes them everywhere you've assigned it:
class A
{
public string Hello { get; set; }
}
class C
{
private A myA;
public C(A a) { myA = a; }
public A GetMyA() { return myA; }
}
// somewhere else:
A someA = new A();
someA.Hello = "Hello World";
C someC = new C(someA);
someA.Hello = "Other World";
Console.WriteLine(someC.GetMyA().Hello);
// this will print "Other World" and not "Hello World" as you suggest
PS: since you were posting pseudocode, I hope you don't mind me simplifying it a bit. If I misunderstood your question, then please disregard (and perhaps clarify, if possible).
PPS: rereading your (edited) code and still trying to figure out what the problem is, there seems to be nothing that prevents C in your code from keeping a member with a reference to A and calling a.Add will obviously reflect the member variable in c as well. Indeed, no need for ref here.

Related

Why is the original object changed after a copy, without using ref arguments?

At work we were encountering a problem where the original object was changed after we send a copy through a method. We did find a workaround by using IClonable in the original class, but as we couldn't find out why it happened in the first place.
We wrote this example code to reproduce the problem (which resembles our original code), and hope someone is able to explain why it happens.
public partial class ClassRefTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var myclass = new MyClass();
var copy = myclass;
myclass.Mystring = "jadajadajada";
Dal.DoSomeThing(copy);
lit.Text = myclass.Mystring; //Text is expected to be jadajadajada,
but ends up to be referenced
}
}
public class MyClass
{
public string Mystring { get; set; }
}
public static class Dal
{
public static int? DoSomeThing(MyClass daclass)
{
daclass.Mystring = "referenced";
return null;
}
}
As you can see, in the DoSomething() method we're not using any ref argument, but still the lit.Text ends up to be referenced.
Why does this happen?
It is always interesting to explain how this works. Of course my explanation could not be on par with the magnificiency of the Jon Skeet one or Joseph Albahari, but I would try nevertheless.
In the old days of C programming, grasping the concept of pointers was fundamental to work with that language. So many years are passed and now we call them references but they are still ... glorified pointers and, if you understand how they work, you are half the way to become a programmer (just kidding)
What is a reference? In a very short answer I would tell. It is a number stored in a variable and this number represent an address in memory where your data lies.
Why we need references? Because it is very simple to handle a single number with which we could read the memory area of our data instead of having a whole object with all its fields moved along with our code.
So, what happens when we write
var myclass = new MyClass();
We all know that this is a call to the constructor of the class MyClass, but for the Framework it is also a request to provide a memory area where the values of the instance (property, fields and other internal housekeeping infos) live and exist in a specific point in time. Suppose that MyClass needs 100 bytes to store everything it needs. The framework search the computer memory in some way and let's suppose that it finds a place in memory identified by the address 4200. This value (4200) is the value that it is assigned to the var myclass It is a pointer to the memory (oops it is a reference to the object instance)
Now what happens when you call?
var copy = myclass;
Nothing particular. The copy variable gets the same value of myclass (4200). But the two variables are referencing the same memory area so using one or the other doesn't make any difference. The memory area (the instance of MyClass) is still located at our fictional memory address 4200.
myclass.Mystring = "jadajadajada";
This uses the reference value as a base value to find the area of memory occupied by the property and sets its value to the intern area where the literal strings are kept. If I could make an analogy with pointers it is as you take the base memory (4200), add an offset to find the point where the reference representing the propery MyString is kept inside the boundaries of the 100 bytes occupied by our object instance. Let's say that the MyString reference is 42 bytes past the beginning of the memory area. Adding 42 to 4200 yelds 4242 and this is the point in which the reference to the literal "jadajadajada" will be stored.
Dal.DoSomeThing(copy);
Here the problem (well the point where you have the problem). When you pass the copy variable don't think that the framework repeat the search for a memory area and copy everything from the original area in a new area. No, it would be practically impossible (think about if MyClass contains a property that is an instance of another class and so on... it could never stop.) So the value passed to the DoSomeThing method is again the reference value 4200. This value is automatically assigned to the local variable daclass declared as the input parameter for DoSomething (It is like you have explicitly done before with var copy = myclass;.
At this point it is clear that any operation using daClass acts on the same memory area occupied by the original instance and you see the results when code returns back to your starting point.
I beg the pardon from the more technically expert users here. Particularly for my casual and imprecise use of the term 'memory address'.
that's normal since your MyClass is a reference type so you are passing a reference to original data not the data itself this why it's an expected behavior
here is an explanation of what a reference type is from Parameter passing in C#
A reference type is a type which has as its value a reference to the appropriate data rather than the data itself
I see two issues here...
Making a Copy of an object
var copy = myClass; does not make a copy - what it really does is create a second reference ("pointer") to myClass (naming the variable "copy" is misleading). So you have myClass and copy pointing to the same exact object.
To make a copy you have to do something like:
var copy = new MyClass(myClass);
Notice that I created a new object.
Passing By Reference
When passing value type variables without ref, the variable cannot be changed by the the receiving method.
Example: DoSomething(int foo) - DoSomething cannot affect the value of foo outside of itself.
When passing value type variables with ref, the variable can be changed
Example: DoSomething(ref int foo) - if DoSomething changes foo, it will remain changed.
When passing an object without ref, the object's data can be changed, but the reference to the object cannot be changed.
void DoSomething(MyClass myClass)
{
myClass.myString = "ABC" // the string is set to ABC
myClass = new MyClass(); // has no affect - or may not even be allowed
}
When passing an object with ref, the object's data can be changed, and the reference to the object can be changed.
void DoSomething(ref MyClass myClass)
{
myClass.myString = "ABC" // the string is set to ABC
myClass = new MyClass(); // the string will now be "" since myClass has been changed
}
The docs at MSDN say it pretty clearly. Value types are passed as a copy by default, objects are passed as a reference by default. Methods in C#

C# myths about best practices?

My colleague keeps telling me of the things listed in comments.
I am confused.
Can somebody please demystify these things for me?
class Bar
{
private int _a;
public int A
{
get { return _a; }
set { _a = value; }
}
private Foo _objfoo;
public Foo OFoo
{
get { return _objfoo; }
set { _objfoo = value; }
}
public Bar(int a, Foo foo)
{
// this is a bad idea
A = a;
OFoo = foo;
}
// MYTHS
private void Method()
{
this.A //1 -
this._a //2 - use this when inside the class e.g. if(this._a == 2)
A //3 - use this outside the class e.g. barObj.A
_a //4 -
// Not using this.xxx creates threading issues.
}
}
class Foo
{
// implementation
}
The this. is redundant if there isn't a name collision. You only need it when you need a reference to the current object or if you have an argument with the same name as a field.
Threading issues have nothing to do with it. The confusion maybe comes from the fact that most static members are implemented so that they are thread-safe and static members cannot (!) be called with this. since they aren't bound to the instance.
"Not using this.xxx creates threading
issues"
is a complete myth. Just ask your co-worker to check the generate IL and have him explain why they are the same whether you add this or not.
"use this when inside the class e.g.
if(this._a == 2)"
is down to what you want to achieve. What your co-worker seems to be saying is always reference the private field, which does not seem to me sensible. Often you want to access the public property, even inside a class, since the getter may modify the value (for instance, a property of type List may return a new List instance when the list is null to avoid null reference exceptions when accessing the property).
My personal "best practice" is to always use this. Yes it's redundant but it's great way to identify from the first look where the state of the instance is chaged or retrieved when you consider multi-threaded app.
It may help to ask your co-worker why he considers these suggestions are best practice? Often people quote best-practice "rules" that they have picked up somewhere without any real understanding of the reasons behind the practices.
As Lucero says, the "this" is not required unless () there is a name collision. However, some people like to include the "this" when it is not strictly required, because they believe it enhances readability / more clearly shows the programmers intentions. In my opinion, this is a matter of personal preference rather than anything else.
As for the "bad idea" in your "Bar" method: Your co-worker may consider this bad practice for the following reason: if the setter method for "A" is altered to have some side effect then A=a; will also produce this side effect, whereas _a = a; will just set the private variable. In my view, best practice is a matter of being aware of the difference rather than prefering one over another.
Finally, the "threading issues" are nonsense - AFAIK "this" has nothing to do with threading.
The number 2 is a myth that is easily debunked by mentioning automatic properties. Automatic properties allow you to define a property without the backing field which is automatically generated by the compiler. So ask your co-worker what is his opinion about automatic properties.

Using Closures to keep track of a variable: Good idea or dirty trick?

Ok, i have a need to be able to keep track of value type objects which are properties on another object, which cannot be done without having those properties implement an IObservable interface or similar. Then i thought of closures and the famous example from Jon Skeet and how that prints out 9 (or 10) a bunch of times and not an ascending order of numbers. So i thought why not do this:
Class MyClass
{
...
Func<MyValueType> variable;
...
public void DoSomethingThatGetsCalledOften()
{
MyValueType blah = variable(); //error checking too not shown for brevity
//use it
}
...
}
... in some other consuming code ...
MyClass myClass = new MyClass();
myClass.variable = () => myOtherObject.MyOtherProperty;
//then myClass will get the current value of the variable whenever it needs it
Obviously this would require some understanding of how closures work, but my question is this: is this a good idea or a dirty hack and a misuse of the closure system?
Edit: Since some people seem to be misunderstanding what i'm trying to say, here's a console program which demonstrates it:
using System;
using System.Linq;
namespace Test
{
class Program
{
public static void Main()
{
float myFloat = 5;
Func<float> test = () => myFloat;
Console.WriteLine(test());
myFloat = 10;
Console.WriteLine(test());
Console.Read();
}
}
}
That will print out 5 then 10.
You have stumbled upon the famous koan: Closures are a poor man's object. You are using Action<T> to substitute for a property getter of type T. Such a thing would be (slightly) less of a dirty trick in a more dynamic language, since it could be implemented by injecting a getter that’s decorated with your logging function, but in C# there isn’t an elegant way to monkeypatch someone’s property when they’re not expecting it.
As a mechanism for obtaining the value fro a property, it'll work (but it won't provide any mechanism for noticing updates promptly). However, it depends on how you intend to use it. To do this conveniently you'll need to use a pile of lambdas in the code, or have some DynamicMethod / Expression code do it at runtime. In most cases, something more similar to reflection would be more convenient.
I wouldn't necessarily worry about the "value type" aspect; in most cases this isn't a bottleneck, despite the FUD - and it is generally a lot easier to handle such code with object than it is via generics or similar.
I have some code in my IDE that demonstrates DynamicMethod vs raw reflection (that I intend to blog some day soon), showing how reflection-based code doesn't have to be slow (or just use HyperDescriptor).
The other option is to implement the correct interfaces / add the correct events. Perhaps via PostSharp, perhaps via dynamic types (inheriting and overriding at runtime), perhaps with regular code.
You would need to type your variable member as Func<MyValueType> (or another delegate that returns MyValueType), but you wouldn't be able to assign the value of blah in that manner. Just as with using the closure in the foreach loop above, it's only going to evaluate at a point in time. This isn't a way to keep your variable's value in sync with the other object. There is, in fact, no way to do that without either:
continuously monitoring the value of the other instance's property in some sort of loop, like a Timer
implementing a change notification event on the other instance's class
You would be able to implement a property like that (since a property is evaluated at every call), but then what's the sense in using a custom delegate, other than the fact that you don't have to know anything about the other instance.
Edit
I'll try to make this a little clearer. Using this code that you posted:
Class MyClass
{
...
Action<MyValueType> variable;
...
MyValueType blah = variable();
//use it
...
}
...
MyClass myClass = new MyClass();
myClass.variable = () => myOtherObject.MyOtherProperty;
First, for this to be functional, variable should be Func<MyValueType>, not Action<MyValueType> (Func returns a value, Action does not; since you're trying to assign a value to a variable, you need the expression to return a value).
Second, the main issue with your approach is--assuming I'm reading your code correctly--you're attempting to assign the value of the instance variable blah to the evaluated value of variable() within the class declaration. This won't work for a couple of reasons:
assignments within class declarations cannot access instance members (which variable is)
the assignment of a variable within a class declaration just occurs upon construction of the object. Even if the first condition were present, you would simply get a NullReferenceException upon instantiating your object, since it would be trying to evaluate variable, which would be null at that time
even disregarding the first two, the value of blah would still only represent the evaluated value of variable() at whatever time it was evaluated. It would not "point to" that function and be automatically kept in sync, as it seems like you're trying to do.
If you aren't looking for some sort of automatic synchronization, then there's nothing stopping you from just keeping the Func<MyValueType> delegate around to evaluate; there's nothing particularly good or bad about that approach, and it isn't a closure unless the delegate (in your case a lambda expression) involves the use of a local variable.

why C# does not provide internal helper for passing property as reference?

This is issue about LANGUAGE DESIGN.
Please do not answer to the question until you read entire post! Thank you.
With all helpers existing in C# (like lambdas, or automatic properties) it is very odd for me that I cannot pass property by a reference. Let's say I would like to do that:
foo(ref my_class.prop);
I get error so I write instead:
{
var tmp = my_class.prop;
foo(tmp);
my_class.prop = tmp;
}
And now it works. But please notice two things:
it is general template, I didn't put anywhere type, only "var", so it applies for all types and number of properties I have to pass
I have to do it over and over again, with no benefit -- it is mechanical work
The existing problem actually kills such useful functions as Swap. Swap is normally 3 lines long, but since it takes 2 references, calling it takes 5 lines. Of course it is nonsense and I simply write "swap" by hand each time I would like to call it. But this shows C# prevents reusable code, bad.
THE QUESTION
So -- what bad could happen if compiler automatically create temporary variables (as I do by hand), call the function, and assign the values back to properties? Is this any danger in it? I don't see it so I am curious what do you think why the design of this issue looks like it looks now.
Cheers,
EDIT As 280Z28 gave great examples for beating idea of automatically wrapping ref for properties I still think wrapping properties with temporary variables would be useful. Maybe something like this:
Swap(inout my_class.prop1,inout my_class.prop2);
Otherwise no real Swap for C# :-(
There are a lot of assumptions you can make about the meaning and behavior of a ref parameter. For example,
Case 1:
int x;
Interlocked.Increment(ref x);
If you could pass a property by ref to this method, the call would be the same but it would completely defeat the semantics of the method.
Case 2:
void WaitForCompletion(ref bool trigger)
{
while (!trigger)
Thread.Sleep(1000);
}
Summary: A by-ref parameter passes the address of a memory location to the function. An implementation creating a temporary variable in order to "pass a property by reference" would be semantically equivalent to passing by value, which is precisely the behavior that you're disallowing when you make the parameter a ref one.
Your proposal is called "copy in - copy out" reference semantics. Copy-in-copy-out semantics are subtly different from what we might call "ref to variable" semantics; different enough to be confusing and wrong in many situations. Others have already given you some examples; there are plenty more. For example:
void M() { F(ref this.p); }
void F(ref int x) { x = 123; B(); }
void B() { Console.WriteLine(this.p); }
If "this.p" is a property, with your proposal, this prints the old value of the property. If it is a field then it prints the new value.
Now imagine that you refactor a field to be a property. In the real language, that causes errors if you were passing a field by ref; the problem is brought to your attention. With your proposal, there is no error; instead, behaviour changes silently and subtly. That makes for bugs.
Consistency is important in C#, particularly in parts of the language that people find confusing, like reference semantics. I would want either references to always be copy-in-copy-out or never copy-in-copy-out. Doing it one way sometimes and another way other times seems like really bad design for C#, a language which values consistency over brevity.
Because a property is a method. It is a language construct responding to a pattern of encapsulating the setting and retrieval of a private field through a set of methods. It is functionally equivalent to this:
class Foo
{
private int _bar;
public int GetBar( ) { return _bar; }
public void SetBar( ) { _bar = value; }
}
With a ref argument, changes to the underlying variable will be observed by the method, this won't happen in your case. In other words, it is not exactly the same.
var t = obj.prop;
foo(ref t);
obj.prop = t;
Here, side effects of getter and setter are only visible once each, regardless of how many times the "by-ref" parameter got assigned to.
Imagine a dynamically computed property. Its value might change at any time. With this construct, foo is not kept up to date even though the code suggests this ("I'm passing the property to the method")
So -- what bad could happen if
compiler automatically create
temporary variables (as I do by hand),
call the function, and assign the
values back to properties? Is this any
danger in it?
The danger is that the compiler is doing something you don't know. Making the code confusing because properties are methods, not variables.
I'll provide just one simple example where it would cause confusion. Assume it was possible (as is in VB):
class Weird {
public int Prop { get; set; }
}
static void Test(ref int x) {
x = 42;
throw new Exception();
}
static void Main() {
int v = 10;
try {
Test(ref v);
} catch {}
Console.WriteLine(v); // prints 42
var c = new Weird();
c.Prop = 10;
try {
Test(ref c.Prop);
} catch {}
Console.WriteLine(c.Prop); // prints 10!!!
}
Nice. Isn't it?
Because, as Eric Lippert is fond of pointing out, every language feature must be understood, designed, specified, implemented, tested and documented. And it's obviously not a common scenario/pain point.

C# this.everything?

I've decided to use this.variableName when referring to string/int etc.. fields.
Would that include ArrayList, ListBox etc too?
Like:
private ListBox usersListBox;
private void PopulateListBox()
{
this.usersListBox.Items.Add(...);
}
...Or not?
And what about classes?
MyClass myClass;
private void PlayWithMyClass()
{
this.myClass = new MyClass();
this.myClass.Name = "Bob";
}
?
This looks kind of odd to me.
And I don't know if I should use this.PublicProperty or only private fields.
I'm not 100% with the C# terminology, but hopefully what I said makes sense.
I used to do that sort of thing, but now I find that IDEs are pretty smart about giving me a visual indication that I'm dealing with a member variable. I only use "this" when it's necessary to distinguish the member variable from a parameter of the same name.
the this. command will allow you to call anything that is in scope in the same class as you are executing. You can access private and public variables and since everything in c# is a object calling a class is the same as calling a string.
You don't have to use this in your code if you don't want to as it is implied in c# unless a method param and a global variable are the same.
Less is more. Less text to parse is more readable.
I use this in the constructors since my parameters and member variables have the same names (I don't like marking member variables with _).
public class A
{
int a;
public A(int a)
{
this.a = a;
}
}
If your class is small enough and does one thing well, then usually you wouldn't need to add this for the sake of readability.
If you can read the whole class easily, what would be the point? It'd be more typing and clutter the code, thus possibly degrade the readability
using the 'this' keyword can be against any instance of an object. So this means u can use it to reference a class instance (eg. usersListBox, myClass, etc).
It's perfectly fine.
Some people use it to clearly explain what they are referencing so people understand that the instances are in the scope of the code and not external or part of another instance or static member elsewhere.
Finally, you can use it to reference both private and/or public properties and fields and members.
This is nothing more then a keyword pointing to the current instance. In a function, this.foo is generally the same as foo.
As msdn tells you:
The this keyword refers to the current instance of the class.
The page about the this keyword contains a lot more info.
As the this. is implicit you only need to actually use it when disambiguating between class variables and local variables of the same name.
The examples you've given would work how you've written then or like this:
private ListBox usersListBox;
private void PopulateListBox()
{
usersListBox.Items.Add(...);
}
MyClass myClass;
private void PlayWithMyClass()
{
myClass = new MyClass();
myClass.Name = "Bob";
}
it's just a matter of personal preference. If you do choose one over the other, try to be consistent.

Categories