int is just a placeholder for another class here
Whoa there! int
is not just "another class". int
is a value type. You can't have a field that's a reference to it. You can have a ref
parameter. In C#7 you can have ref
returns and locals, but still not fields.
In the CLR, int
is critically different from classes in exactly the area we're talking about here. x
is an int on what we'll figuratively call "the stack", since I don't feel like looking up how they actually implemented it. In C, I seem to recall describing that as a stack variable:
int x = 0;
List<T>
is a class. y
, here, is a "stack variable" which is a rebindable reference to an object on the "heap":
var y = new List<int>();
If you're talking about sharing references to reference types -- any class
-- in C# that's easy: It's always a reference.
public class C {
// x is passed by value. It is the value of a reference. Seriously, it is.
public C(List<String> x) {
List = x;
}
public List<String> List { get; set; }
}
...
var list = new List<String>();
var x = new C(list);
var y = new C(list);
x.List
and y.List
are the same object, at least until you assign a new object to one of them -- C# references, unlike C++ references (at least as of C++98; I haven't kept up since 2006) are "rebindable".
The way to do this is to write a simple class with an int
property, and share a reference to an instance of that. where T : struct
restricts T
to be a struct
rather than a class. In CLR-land, that means "value type" rather than "reference type".
public class Reference<T> where T : struct
{
public Reference(T t) {
Value = t;
}
public T Value { get; set; }
}
class MyClass
{
MyClass(Reference<int> ref)
{
_ref = ref;
}
Reference<int> _ref;
}
Why did C# take away the functionality to create reference member variables?
They didn't "take it away"; they didn't abduct an infant C++ compiler and cut its toes off. They just didn't think it was a good idea to do that in C#, and they were right. C# isn't C and it isn't meant to be C. Dennis Ritchie designed C to be used by people like Ken Thompson; Anders Hejlsberg explicitly designed C# to be used by the rest of us, who are much more easily confused.
This is built deeply into .NET:
The CLR type system however does not allow for fields that are aliases to other variables
(That's an old essay; C#7 now does support the additional uses of ref
that the CLR supported all along).
New C# programmers already have more than enough trouble with ref
and reference types. Just recently I saw code in a question here much like this:
public void F(ref List<int> x) { ... }
The fellow who wrote that code just wanted to pass in a List<int>
without creating an expensive copy of it.