What I want to do is, I want to pass a pointer to a function that may be any type of a variable(int, long, string, even a class I mean I should be able to pass any variable's pointer). I'm doing this like that
unsafe class whatever
{
whatever(object* variable)
{
this.variable = variable;
}
}
ERROR IS: Cannot take the address of, get the size of, or declare a pointer to a managed type ('object')
Why I want to do is, I will store the variables passed through the constructor and will use their ToString() method, I'm trying to make a class that is for console applications, Refreshing the variables with their updated variables.
If I could do it like that My code will look like that
unsafe class whatever
{
whatever(object* variable)
{
this.variable = variable;
}
object* variable;
public override string ToString()
{
return *variable.ToString();
}
}
Maybe you should pass in a delegate that your class can use to obtain the “object string”.
class MyFancyClass
{
Func<string> getObjectString;
public MyFancyClass(Func<string> getObjectString)
{
this.getObjectString = getObjectString;
}
private MyOtherThread()
{
// ...
string desc = getObjectString();
// ...
}
}
// ...
long value = 34;
MyFancyClass fancy = new MyFancyClass(() => value.ToString());
// ...
value = 88;
// getObjectString() should now reflect the new value.
// The variable is captured in the lambdas closure.
Be careful though, because the delegate is called from another thread and simply calling ToString() may not be safe for all objects and require locking. However a delegate allows the caller to do this, depending on the object.
Pointers will get ugly, require unsafe code and aren't stable. The garbage collector can move objects around freely, if you don't explicitly make the pointers fixed. References can't be stored and you can only pass them around.
In C#, you usually don't use pointers. If you want to refer to a storage location, try this:
whatever(ref object variable)
{
}
Else, i would rather recommend using a wrapper class or another way to get to some variable.
A wrapper might look like this:
class Wrapper
{
public object Value { get; set; }
}
If you want to get the address of a variable it can't be a complex managed type. However, you can do something like this (assuming an unsafe context):
int a = 1;
IntPtr addr = ( IntPtr )( &a );
( * ( int* ) addr ) = 4;
a = 4;
Is this what you're looking for?
Edit:
If you're just wanting to save a "function pointer" from the object, just use a delegate to hold that.
class whatever
{
public whatever(object variable)
{
getVariableValue = variable.ToString;
}
Func<string> getVariableValue;
public override string ToString()
{
return getVariableValue();
}
}
void Main()
{
var type = new { F1 = "test", F2 = "value" };
whatever w = new whatever( type );
Console.WriteLine( w ); // This will invoke ToString
}
Output: { F1 = test, F2 = value }
You want a void* but becareful with those. if you make the wrong cast it will crash. it might be a wise idea to make a struct and cast to an intptr in this case.
Related
In C#, is there a way to keep a reference as a member variable in an object (like an object pointer in C++), not just as a parameter?
EDIT: How can I make a pointer or reference to an object as a member variable?
No. Don't forget that the argument could reference a local variable which is out of scope by the time you use the object later on. A couple of options:
Use a mutable wrapper type
Use a delegate which captures the variable instead
Redesign your code to not require this in the first place
It's hard to know which is most suitable without knowing more about what you're trying to achieve, but ref is a dead-end.
If you mean ref the argument passing convention, then no, you cannot store this. From the first note on MSDN:
Do not confuse the concept of passing by reference with the concept of reference types. The two concepts are not the same...
Edit: based on your updated question, C# has different nomenclature about pointers and references. A pointer in C# is an unsafe construct used to somewhat directly reference the memory location of an object. I say somewhat because the memory location can change based on garbage collection (unless you fix it in memory).
References in C# are the default way reference types are passed and stored. They are akin to pointers in other languages, but not quite the same. However, the by-reference argument passing convention allows you to directly change what an object refers to.
If your objective is to keep a mutable reference to a non-reference type local variable, you'll have to encapsulate the local variable in a reference type (like a class). If you could give some sample code, we can give some specific examples.
Yes if it is a reference-type instance. And then it is the only way to store it in another class:
class Bar { }
class Foo
{
private Bar b; // b is a reference to a Bar
}
No if it's about a value-type, or a reference to a reference.
You would see simple object-references everywhere that C++ uses pointers, like in building Trees or Linked-Lists.
class Element { ...; private Element _next; }
For what its worth, you could use an array of size 1 as a reference/pointer. This yields more readable code than creating a new class to wrap a single value type member.
public struct StructWithReferenceMember
{
private int[] intStoredAsReference;
public StructWithReferenceMember(int asValue, int asReference)
: this()
{
IntStoredAsValue = asValue;
intStoredAsReference = new int[] { asReference };
}
public int IntStoredAsValue { get; set; }
public int IntStoredAsReference
{
get { return intStoredAsReference[0]; }
set { intStoredAsReference[0] = value; }
}
}
A similar trick can be used to attempt the highly discouraged practice of using mutable structs.
public class ReferenceProperty<T>
{
private T[] typeReference;
public ReferenceProperty(T value)
{
typeReference = new T[] { value };
}
public T PropertyAsValue
{
get { return typeReference[0]; }
set { typeReference[0] = value; }
}
public T[] PropertyAsReference
{
get { return typeReference; }
}
}
Then use array notation to "dereference" it.
public struct MutableStruct
{
public int member;
public MutableStruct(int value)
{
member = value;
}
}
ReferenceProperty<MutableStruct> referenceToValueType = new ReferenceProperty<MutableStruct>(new MutableStruct(3));
Console.WriteLine("original value: " + referenceToValueType.PropertyAsValue.member.ToString());
//referenceToValueType.PropertyAsValue.member = 4; // compiler error - cannot modify return value because it is not a variable
MutableStruct copyOfStruct = referenceToValueType.PropertyAsReference[0]; // or referenceToValueType.PropertyAsValue
copyOfStruct.member = 4;
Console.WriteLine("original value after modifying copy: " + referenceToValueType.PropertyAsValue.member.ToString());
referenceToValueType.PropertyAsReference[0].member = 5;
Console.WriteLine("original value after modifying reference: " + referenceToValueType.PropertyAsValue.member.ToString());
original value: 3
original value after modifying copy: 3
original value after modifying reference: 5
The way to get the address of a variable is the & operator, similar to C++. Again similarly to C++, you can store the address as a pointer:
class Foo
{
object* _objPtr;
Foo(object obj)
{
unsafe
{
_objPtr = &obj;
}
}
}
Note that any code that uses the address-of operator (&) or pointers must be within a method marked unsafe or within an unsafe code block.
This could be useful if you want to increase performance by not doing array bound-checking for example. The downside (besides safety considerations) is that the assembly must be fully-trusted for it to execute.
As pointed out, in C#, you very rarely actually store pointers, instead you store references so the garbage collector can operate properly. Ensure that you really need pointers in your code before using them!
For more info, see: http://msdn.microsoft.com/en-us/library/y31yhkeb.aspx
I want a singleton Problem with a "square" 2x2.
I want to be able to refer to the case by row.
I want to be able to refer to the row by case.
I know I could easily do this in C++ with pointers but it seems like a bad habit to do.
I don't understand how to link my "row" and my "case" together.
The same logic will be there for column but isn't describe in the code
The goal is so changing the value of a Case would affect the value reffered in the Row. How can I achieve this without pointer and with Ref?
class Program
{
static void Main(string[] args)
{
Problem.Instance().Show();
Problem.Instance().Change();
Problem.Instance().Show();
}
public class Problem
{
private Case[] cases = null;
private Row[] rows = null;
// same logic with private Column[] columns = null;
static Problem instance = null;
private Problem()
{
cases = new Case[4];
rows = new Row[2];
int i = 0;
for (i = 0; i < 4; i++)
cases[i] = new Case();
for (i = 0; i < 2; i++)
rows[i] = new Row(i);
}
public static Problem Instance()
{
if (instance == null)
instance = new Problem();
return instance;
}
public Case LinkToRow(int i, ref Row r)
{
cases[i].LinkToRow(r);
return cases[i];
}
public void Show()
{
rows[0].Show();
}
public void Change()
{
cases[0].Change();
cases[1].Change();
}
}
public class Row
{
private Case[] ref cases = null;
public Row(int i)
{
ref Row r = this;
cases = new Case[2];
cases[0] = Problem.Instance().LinkToRow(0, ref r);
cases[1] = Problem.Instance().LinkToRow(1, ref r);
}
public void Show()
{
Console.WriteLine("{0},{1}", cases[0].Val, cases[1].Val);
}
}
public class Case
{
private int val;
private ref Row r = null;
public Case()
{
}
public void LinkToRow(Row rr)
{
r = rr;
}
public int Val { get { return val; } }
public void Change()
{
val++;
}
}
}
In C#, private Row r = null; declares a rebindable reference to an instance of Row. ref is illegal there and not needed.
In C++, private: Row r; would be an instance of Row, not a reference. C++ is a different language with very different rules. C# classes can't "be on the stack"; they're always dynamically allocated, and the only way you can manipulate one is via a reference.
In C#, your private Row r; is already a reference. A C# reference is kind of like a pointer that you don't have to (and can't) explicitly dereference. Because it's always dereferenced, you can't do pointer arithmetic either. They're subject to many of the same polite fictions ("let's make them pretend it's not a pointer") as C++ references. Just take out ref.
A C# struct (e.g. System.DateTime) is more like a stack instance of a C++ class. This is very different from the C++ struct/class distinction.
The C# ref keyword is a different animal. Nothing to do with references.
In C#, the example below illustrates what the ref keyword is for: Passing references by reference instead of by value. That sounds like I'm pulling your leg but I'm not.
To explain it in terms of C++ semantics, passing a C# reference "by value" is like passing a pointer. You can change the object the caller's pointer points at, but you can't change the caller's pointer itself. You have only the value of the caller's pointer.
Passing a C# reference by reference is like passing in a pointer to a pointer: You can set (*p)->Foo = 3;, and you can also set *p = new Bar(); (I'm rusty on C/C++, corrections welcomed).
public static void F()
{
String x = "original value";
FByValue(x);
Console.WriteLine(x);
FByReference(ref x);
Console.WriteLine(x);
}
public static void FByValue(String s)
{
s = "different value for local copy of parameter only";
}
public static void FByReference(ref String s)
{
s = "different value for caller's copy, thanks to ref keyword";
}
ref works only with parameters, never ever with fields; see MSDN for more detail.
Lastly: FByValue() and FByReference() would have identical semantics with int instead of String.
In C# there is a difference between value types and references.
First, there is nothing wrong with pointers in C/C++, that's how the language works and, that's how the hardware works as well. They can just be confusing to the new user.
In C#, the definition of structures and classes is different than C++:
if you define your data structures as struct or as class.
A struct is an object that gets copied around as it is passed from calls to calls. A class on the other hand gets its pointer passed around, similar to a C++ pointer, so if you have references to class instances in C#, you're really referencing the same object, and changes done at one place will be reflected everywhere you hold a reference to that object.
one of the restrictions on Indexers is that indexer does not define a storage location, So a value produced by an indexer cannot be passed as a ref or out parameter to a method.
I was wondering the array that we define for indexer isn't a storage location?
I am going to break down each part of your question and try to help you out.
Does Index Define a Location in Storage?
one of the restrictions on Indexers is that indexer does not define a storage location
If saying is "a location somewhere in storage is not guaranteed to be abstractedly defined in the classes implementation of that index" then yes that is correct, abstractly you are defining a value at the Index of the value of your indexer, but that does not guarantee you are accessing a logical location (at an abstract level, at a low level everything has a location). Basically an index is a pretty way to represent a method that takes a value and returns a value a variable(s) that indicates location and using syntax of brackets, and the equal sign to determine which method to call (get or set). I feel like I am getting off topic but you can look up more info on index implementation on on MSDN. But just like methods you have to make it make sense. Here is an example of failing at that making sense and also not having an actual location on the back end of the implementation.
A Weird Example
public class MyClass
{
private void Set(int i,string value)
{
Console.WriteLine("Your Index:{0}\r\nSet Value:{1}",i,value);
}
public string this[int i]
{
get
{
if(i<0)
return "less than zero";
if(i==0)
return "This is zero";
else if(i==1)
return "This is one";
else if(i==2)
return "this is two";
else
return "more than two";
}
set
{
//value is a key word in a setter
//representing the value on you are attempting to set
Set(i,value);
}
}
}
Don't do this
Why you would want to do this I am not sure sure, but if you did want to you could, indexers are just a nice way of expressing a method where it makes sense that it is acting as an index, such as in a Dictionary or a List, and while someone might try to argue that technically the getter in this example does it still makes no sense and shouldn't be using an index to express the method
Can You Pass an Index by ref or out to a Method
So a value produced by an indexer cannot be passed as a ref or out parameter to a method.
since the data you are accessing through the index is encapsulated in the class unless the class exposes a reference to that data you cannot accesses it, therefore you cannot use pass it as a ref or an out parameter in a method call for an indexer property, so we need to see if accessing the indexer exposes a location in memory
Short Answer
No, the key words `ref` and `out` basically tell the IL to make the method take a memory address, `out` requiring the location in memory be assigned a new value, `ref` not requiring a change but still allowing it to happen, since all indexes and properties are not supported in all languages in .NET they are implemented by changing the instructions in "get" and "set" into method calls, `ref` and `out` needs a location in memory of the passed variable, reduced to IL trying to treat a get/set of an indexer as an out variable is equivalent to trying to treat a method or a fresh variable as a `ref` or `out` parameter which is semantically invalid
Long Answer
You cannot, the reason why is because you are calling a method when you use the indexer, say you have this as the method you want to a call
public void CreateNew(out object target)
{
target = new object();
}
What is happening
When you call the CreateNew method at some level instructions:
Take CreateNew Instruction Location
Puts The Location of the variable passed to target into a parameter slot
Changes the value of the memory in the location to a place in the heap
holding the object created by the "new object();" statement
Returns control
It Doesn't work with an indexer
An indexer is called in two cases
Get:
the indexer "Get" method appears where the object is indexed and is trying to be accessed. When this happens a method call is made to some method that represents your get method that has a signature like
ValueType _get_index_IndexType_ValueType( IndexType index)
so if the compiler resolved your call to this as the out parameter then it would be like trying to pass a reference to a variable that hasn't been assigned a location in memory yet. That is why it wouldn't work with the "Get" method and this was done by design as logically you cannot access a location in memory for a variable from the location in memory of an object.
Set:
The indexer "Set" method appears when the object is indexed and on the left hand side of an equal sign, internally it is replace with some method that represents your set method that has a signature like this
void _set_index_IndexType_ValueType(IndexType index, ValueType Value)
So if the call reduces to this it would be the same thing as trying to access the location in memory of a method call, this is not what we want, what we want to do is call the set method when giving a new variable to the index, and get when we are trying to access it. However by design this is not allowed, as you can easily do this on your own...
More Code
If this still doesn't make sense try thinking of the class below, where instead of having an indexer method we just use a Get and Set with an index
public class MyFooIndexableObject
{
/* Note that "ValueType" and "IndexType" are
* just place holders for whatever type you
* decide to make as your return type and
* index type respectively
*
* Using a regular dictionary and an
* extra variable to implement a default
* dictionary so it is not like the example
* is doing nothing.
*/
private Dictionary _internalCollection;
private readonly ValueType _defaultValue = new ValueType();
public void FooSet(IndexType index, ValueType value)
{
if( index == null)
//want to disallow index being null
throw new NullArgumentException("index");
if(_internalCollection==null)
_internalCollection = new Dictionary();
if ( value == null || value == _defaultValue )
// want to remove it
{
_internalCollection.Remove(index);
}
else
_internalCollection[index]=value;
}
/* The Examples FooSet and FooGet
* would be similar method constructs to
* the ones made behind the scenes when
* you define the getter and setter for
* your indexed object
*/
public ValueType FooGet(IndexType index)
{
if( _internalCollection == null
|| !_internalCollection.Contains(index) )
return new _defaultValue;
return _internalCollection[index];
}
public bool TryGetValueAtFirstNonDefault(out IndexType outIndex,
out ValueType outValue)
{
outParam = outIndex = null;
if(_internalCollection!=null)
{
// no need to check we maintain this in the setter and getter
var temp= _internalCollection.FirstOrDefault();
if(temp!=null)
{
outParam = temp.Value;
outIndex = temp.Key;
}
}
return outParam != null;
}
private static void Swap( ref ValueType someRefParam,
ref ValueType otherRefParam)
{
var temp = someRefParam;
someRefParam = otherRefParam;
otherRefParam = temp;
}
//use this instead
public void SwapValueAtIndexes(IndexType index1, IndexType index2)
{
var temp = this.FooGet(index1);
this.FooSet(index1, this.FooGet(index2) );
this.FooSet(index2, temp);
}
public static void Main(string[] args)
{
var indexable = new MyFooIndexableObject();
var index1 = new IndexType(0);
var index2 = new IndexType(1);
ValueType someValue;
//do someValue = indexable[index1]
someValue = indexable.FooGet(index1);
//do indexable[index1] = new ValueType()
indexable.FooSet(index1,new ValueType());
//this does not make sense will not work
//do Swap( out indexable[index1], out indexable[index2] )
//just look how you would try to do this
Swap( ref indexable.FooGet(index1), ref indexable.FooGet(index2));
//Swap is looking for reference to a location in memory
//but the method is returning the value of an object reference
//which you can store in a variable with a location in memory
//but has yet been assigned to one
//Please note the whole idea of "location in memory" is abstract
//it does not technically mean an actual location in physical
//memory but probably an abstraction handled by .NET,
//don't try to hard to make sure you have the technical part
//100% correct, you are significantly detached from the metal
//when coding at this level...the basic idea is the same
//as physical memory locations on a machine
//However, you can accomplish the same things that you would
//want to accomplish with "out" and "ref" by creating methods
//that take the indexed object and an index, such as the
//SwapValueAtIndex method
indexable.SwapValueAtIndex(index1,index2);
//While precisely what SwapValueAtIndex does may
//not translate to what Swap does logically
//it is the same thing, which is good enough for us
}
}
But You Can...
Even though you can't get to the actual reference of the object you can pass the index and the indexed object to a method, this will effectively give you the same effect as a reference to the variable because you can access it using the index and the object that it is located in
public void Swap(MyIndexedObject o, string indexer, object newValue,
ref object oldValue)
{
if(o.Contains(indexer))
{
oldValue = o[indexer];
}
else
oldValue = null;
o[indexer]=newValue;
}
public bool TryGetValue(MyIndexedObject o, string index, out object value)
{
value=null;
if(o.Contains(index))
{
value = o[value];
return true;
}
return false;
}
public void TrySwapValue(MyIndexedObject o, string indexer1, string indexer2)
{
object valHolder1=null,valHolder2=null;
if(TryGetValue(o,indexer1, out valHolder1))
{
Swap(o, indexer2, valHolder1,ref valHolder2);
o[indexer1] = valHolder2;
}
}
What that Means
As you can see you can logically use an index as a location (in a case where the indexed object implementation makes sense) if you have the object, that is where indexed objects make sense to use
Other Options
If you still want a reference to an indexed object you can define a class that has an index and gets and sets the value of the object, in this you could include thing like a history
public class MyObject : Dictionary{}
public class MyPlaceHolder
{
public MyPlaceHolder(string index, MyObject target)
{
Index = index;
TargetObject = target;
}
public string Index {get; private set;}
public MyObject TargetObject {get; private set;}
public object Value
{
get
{
return TargetObject[Index];
}
set
{
var prev = TargetObject[Index];
TargetObject[Index] = value;
_prevVals.Push(prev);
}
}
private Stack _prevVals = new Stack();
public bool UndoSet()
{
if(!_preVals.Count() == 0)
{
Value._prevVals.Pop();
return true;
}
return false;
}
}
Is a Storage Location in Existence for an Index?
I was wondering the array that we define for indexer isn't a storage location?
Yes that array is a location, but the index definition is not a direct reflection of that address. An index into an object is an abstraction of the the concept of an Index, which is something that allows you to access an object based on an index value you pass into it, it does not necessarily do that but it should, technically it could be a method that has nothing to do with a location but it shouldn't.
However the way the object does not expose the actual location underneath is correct, you are using encapsulation to hide the way the location specified by your index method, which is one of the reasons we have object oriented programming I don't care if 0 is a location at the level of the implementation as long as it makes sense when I use it
A Better Example of using an Index
I feel bad for only creating one example of an Indexed object that is actually awful and something hopefully no one ever mistakenly thinks is a good idea, so will show why it makes sense to hide location, this is the purpose behind the abstraction of an index
Let's say I want to make a double key dictionary, I know in some part of my code I am going to implement it, but I don't know how yet, if you have multiple people working so you don't want people to wait around while you code the class, so you can define the interface, and implement it while the other programmers work
public interface IMyDoubleStringDictionaryBase<T>
{
T this[string index1, string value2]
{
get;set;
}
}
The First Implementation
You decide to make it using nested dictionaries, this is what you come up with
public class MyDoubleStringDictionary<T> : IMyDoubleStringDictionaryBase<T>
{
private Dictionary<string,Dictionary<string,T>> _baseCollection;
public T this[string index1, string index2]
{
get
{
if(_baseCollection.ContainsKey(index1))
{
var nextDict = _baseCollection[index1];
if(nextDict.ContainsKey(index2))
{
return nextDict[index2];
}
}
return default(T);
}
set
{
Dictionary<string,T> nextDict;
if(_baseCollection.Contains(index1))
{
nextDict = _baseCollection[index1];
}
else
{
nextDict = new Dictionary<string,T>();
_baseCollection.Add(index1,nextDict);
}
nextDict[index2] = value;
}
}
}
You Have a Problem
For some reason the Dictionary class is not available to you in your production environment, while this might not make sense to you you are told to make one using only the Array data structure, all other abstract data structures you need to define yourself. You decide to make a bucket hash that takes the two hashes of the keys and mixes them
public class MyNewDoubleStringDictionary<T> : IMyDoubleStringDictionaryBase<T>
{
private class Node<T>
{
public Node<T> Next;
public string Key1,Key2;
public T Value;
}
private const int ARRAY_SIZE = 1024;
private Node<T>[] _internalCollection = new Node<T>[ARRAY_SIZE];
private int GetIndex(string key1, string key2)
{
const int key1mask = 0x0F0F0F0F;
const int key2mask = 0xF0F0F0F0;
var key1 = key1mask & key1.GetHashCode();
var key2 = key2mask & key2.GetHashCode();
var result = ((key1 | key2) & 0x7FFFFFFF)% ARRAY_SIZE;
return result;
}
private Node<T> GetOrMakeNode(string key1,string key2)
{
int index = GetIndex(key1,key2);
Node<T> currNode=_internalCollection[index];
if(currNode == null)
{
_internalCollection[index] = currNode = new Node<T>();
}
else
{
while(!(currNode.Key1.Equals(key1)
&&currNode.Key2.Equals(key2))
if(currNode.Next!=null)
{
currNode = currNode.Next;
}
else
{
currNode.Next = new Node<T>();
currNode = currNode.Next;
}
}
if(currNode.Key1 == null || currNode.Key2 == null)
{
currNode.Key1 = key1;
currNode.Key2 = key2;
}
return currNode;
}
public this[string index1, string index2]
{
get
{
var node = GetOrMakeNode(index1,index2);
return node.Value;
}
set
{
var node = GetOrMakeNode(index1,index2);
node.Value = value;
}
}
}
The Result
Even though you had a change in requirements and implementation it did not interrupt any of your team's work, because you aren't making references to internal workings of objects so it would be impossible for it to mess up their work.
Why it Makes Sense
You don't care where the location is, you shouldn't really be worried if the actual implementation is looking at a location just know that you have to interface the index in a certain way and you will be able to use it
http://msdn.microsoft.com/en-us/library/vstudio/6x16t2tx.aspx
Indexer are just special getters and setters. And ref or out are always just local variables. Indexer doesn't even have to point to a storage location but can return computed values.
Indexer don't even have to be used on arrays. For example in a vector image i could define indexers myvectorimage[x][y] such that it returns the color at a x and y location but the data is never stored that way.
In C#, is there a way to keep a reference as a member variable in an object (like an object pointer in C++), not just as a parameter?
EDIT: How can I make a pointer or reference to an object as a member variable?
No. Don't forget that the argument could reference a local variable which is out of scope by the time you use the object later on. A couple of options:
Use a mutable wrapper type
Use a delegate which captures the variable instead
Redesign your code to not require this in the first place
It's hard to know which is most suitable without knowing more about what you're trying to achieve, but ref is a dead-end.
If you mean ref the argument passing convention, then no, you cannot store this. From the first note on MSDN:
Do not confuse the concept of passing by reference with the concept of reference types. The two concepts are not the same...
Edit: based on your updated question, C# has different nomenclature about pointers and references. A pointer in C# is an unsafe construct used to somewhat directly reference the memory location of an object. I say somewhat because the memory location can change based on garbage collection (unless you fix it in memory).
References in C# are the default way reference types are passed and stored. They are akin to pointers in other languages, but not quite the same. However, the by-reference argument passing convention allows you to directly change what an object refers to.
If your objective is to keep a mutable reference to a non-reference type local variable, you'll have to encapsulate the local variable in a reference type (like a class). If you could give some sample code, we can give some specific examples.
Yes if it is a reference-type instance. And then it is the only way to store it in another class:
class Bar { }
class Foo
{
private Bar b; // b is a reference to a Bar
}
No if it's about a value-type, or a reference to a reference.
You would see simple object-references everywhere that C++ uses pointers, like in building Trees or Linked-Lists.
class Element { ...; private Element _next; }
For what its worth, you could use an array of size 1 as a reference/pointer. This yields more readable code than creating a new class to wrap a single value type member.
public struct StructWithReferenceMember
{
private int[] intStoredAsReference;
public StructWithReferenceMember(int asValue, int asReference)
: this()
{
IntStoredAsValue = asValue;
intStoredAsReference = new int[] { asReference };
}
public int IntStoredAsValue { get; set; }
public int IntStoredAsReference
{
get { return intStoredAsReference[0]; }
set { intStoredAsReference[0] = value; }
}
}
A similar trick can be used to attempt the highly discouraged practice of using mutable structs.
public class ReferenceProperty<T>
{
private T[] typeReference;
public ReferenceProperty(T value)
{
typeReference = new T[] { value };
}
public T PropertyAsValue
{
get { return typeReference[0]; }
set { typeReference[0] = value; }
}
public T[] PropertyAsReference
{
get { return typeReference; }
}
}
Then use array notation to "dereference" it.
public struct MutableStruct
{
public int member;
public MutableStruct(int value)
{
member = value;
}
}
ReferenceProperty<MutableStruct> referenceToValueType = new ReferenceProperty<MutableStruct>(new MutableStruct(3));
Console.WriteLine("original value: " + referenceToValueType.PropertyAsValue.member.ToString());
//referenceToValueType.PropertyAsValue.member = 4; // compiler error - cannot modify return value because it is not a variable
MutableStruct copyOfStruct = referenceToValueType.PropertyAsReference[0]; // or referenceToValueType.PropertyAsValue
copyOfStruct.member = 4;
Console.WriteLine("original value after modifying copy: " + referenceToValueType.PropertyAsValue.member.ToString());
referenceToValueType.PropertyAsReference[0].member = 5;
Console.WriteLine("original value after modifying reference: " + referenceToValueType.PropertyAsValue.member.ToString());
original value: 3
original value after modifying copy: 3
original value after modifying reference: 5
The way to get the address of a variable is the & operator, similar to C++. Again similarly to C++, you can store the address as a pointer:
class Foo
{
object* _objPtr;
Foo(object obj)
{
unsafe
{
_objPtr = &obj;
}
}
}
Note that any code that uses the address-of operator (&) or pointers must be within a method marked unsafe or within an unsafe code block.
This could be useful if you want to increase performance by not doing array bound-checking for example. The downside (besides safety considerations) is that the assembly must be fully-trusted for it to execute.
As pointed out, in C#, you very rarely actually store pointers, instead you store references so the garbage collector can operate properly. Ensure that you really need pointers in your code before using them!
For more info, see: http://msdn.microsoft.com/en-us/library/y31yhkeb.aspx
I'd like semantics similar to C#'s ref keyword.
Java is confusing because everything is passed by value. However for a parameter of reference type (i.e. not a parameter of primitive type) it is the reference itself which is passed by value, hence it appears to be pass-by-reference (and people often claim that it is). This is not the case, as shown by the following:
Object o = "Hello";
mutate(o)
System.out.println(o);
private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!
Will print Hello to the console. The options if you wanted the above code to print Goodbye are to use an explicit reference as follows:
AtomicReference<Object> ref = new AtomicReference<Object>("Hello");
mutate(ref);
System.out.println(ref.get()); //Goodbye!
private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); }
Can I pass parameters by reference in
Java?
No.
Why ? Java has only one mode of passing arguments to methods: by value.
Note:
For primitives this is easy to understand: you get a copy of the value.
For all other you get a copy of the reference and this is called also passing by value.
It is all in this picture:
In Java there is nothing at language level similar to ref. In Java there is only passing by value semantic
For the sake of curiosity you can implement a ref-like semantic in Java simply wrapping your objects in a mutable class:
public class Ref<T> {
private T value;
public Ref(T value) {
this.value = value;
}
public T get() {
return value;
}
public void set(T anotherValue) {
value = anotherValue;
}
#Override
public String toString() {
return value.toString();
}
#Override
public boolean equals(Object obj) {
return value.equals(obj);
}
#Override
public int hashCode() {
return value.hashCode();
}
}
testcase:
public void changeRef(Ref<String> ref) {
ref.set("bbb");
}
// ...
Ref<String> ref = new Ref<String>("aaa");
changeRef(ref);
System.out.println(ref); // prints "bbb"
From James Gosling in "The Java Programming Language":
"...There is exactly one parameter passing mode in Java - pass by value - and that keeps things simple.
.."
I don't think you can. Your best option might be to encapsulate the thing you want to pass "by ref" onto another class instance, and pass the (outer) class's reference (by value). If you see what I mean...
i.e. your method changes the internal state of the object it is passed, which is then visible to the caller.
Java is always pass by value.
When you pass a primitive it's a copy of the value, when you pass an object it's a copy of the reference pointer.
Another option is to use an array, e.g.
void method(SomeClass[] v) { v[0] = ...; }
but 1) the array must be initialized before method invoked, 2) still one cannot implement e.g. swap method in this way...
This way is used in JDK, e.g. in java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[]).
Check out my response in: http://stackoverflow.com/a/9324155/1676736
In there I used a simpler version of the wrapper class idea.
I don't like setters/getters as a standard. When there is no reason to bury a field I make it 'public'. Especially in something like this.
However, this would work for all but the primitive, or multi-parameter/type returns:
public class Ref<T> {
public T val;
}
Although, I suppose you could just add more type parameters. But I think that creating an inner static class fit-for-purpose would be easier:
public static class MyReturn {
public String name;
public int age;
public double salary;
}
this would be for use when you don't need it for other reasons.
MyReturn mRtn = new MyReturn();
public void myMethod(final MyReturn mRtn){
mRtn.name = "Fred Smith";
mRtn.age = 32;
mRtn.salary = 100000.00;
}
System.out.println(mRtn.name + " " +mRtn.age + ": $" + mRtn.salary);