I understand struct is value type. But I do not understand why it behave like this?
Is it because i didn't treat it as immutable? or is it has something to do with the auto property?
using System;
namespace StructQuestion
{
class Program
{
static StructType structAsProperty { get; set; }
static StructType structAsField;
static void Main(string[] args)
{
structAsProperty.InjectValue("structAsProperty");
structAsField.InjectValue("structAsField");
//debugger says structAsProperty.GetValue() is null
Console.WriteLine(structAsProperty.GetValue());
Console.WriteLine(structAsField.GetValue());
Console.ReadLine();
}
}
public struct StructType
{
private string value;
public void InjectValue(string _value)
{
value = _value;
}
public string GetValue()
{
return value;
}
}
}
Let's look at what happens in this statement:
structAsProperty.InjectValue("structAsProperty");
We don't have to go far. The very first thing that must happen is to resolve the structAsProperty part of the statement. The key here is understanding the compiler re-writes property get and set sections as a method calls behind the scenes.
So what we really have here is a call to a method that returns our struct value. I say "value" here rather than "object" because structs are value types. With value types, passing to or returning from a method results in a copy of the value.
Now we know enough to understand what happened. We are calling InjectValue() on a copy of the property struct, not the instance in the property itself. Next we modify this copy via it's InjectValue() method... and then promptly forget the copy ever existed.
You can fix it like this:
var prop = structAsProperty; //now we have a variable to keep the result of the implicit get accessor method
prop.InjectValue("structAsProperty");
structAsProperty = prop;
Related
Take the following code from http://csharpindepth.com/Articles/Chapter8/PropertiesMatter.aspx:
using System;
struct MutableStruct
{
public int Value { get; set; }
public void SetValue(int newValue)
{
Value = newValue;
}
}
class MutableStructHolder
{
public MutableStruct Field;
public MutableStruct Property { get; set; }
}
class Test
{
static void Main(string[] args)
{
MutableStructHolder holder = new MutableStructHolder();
holder.Field.SetValue(10);
holder.Property.SetValue(10);
Console.WriteLine(holder.Field.Value);
Console.WriteLine(holder.Property.Value);
}
}
(There were a couple of comments in the code I missed earlier or didn't read that I've taken out now.)
The claim on the article is that the output is 10 for holder.Field, but 0 for holder.Property, and this has been verified to be accurate. I'm having a bit of trouble seeing why though. An auto-implemented property will have one specific field set aside that it's mapped to, and due to being a struct, Property will immediately have had its backing field fully set and constructed from the beginning. What's the difference?
The line holder.Property returns a copy of MutableStruct. So when you write holder.Property.SetValue(10) you are changing the copy, not the original.
The line holder.Field is an alias for the MutableStruct itself.
It is really hard to not accidentally make copies of structs. Thus we try to not make them mutable.
The difference is the interjection of a getter for the property. It's functionally equivalent to
private MutableStruct _Property;
public MutableStruct GetProperty()
{
return _Property;
}
public void SetProperty(MutableStruct value)
{
_Property = value;
}
So when you call
holder.Field.SetValue(10);
you are mutating the struct at Field directly, but when you call
holder.Property.SetValue(10);
you are mutating the copy of the struct returned from GetProperty.
Am I misunderstanding something about pass by reference?
SomeClass is the IObserver implementer:
bool value = false;
provider.Subscribe(new SomeClass(ref value));
while (!value)
{
provider.GetEvents() //triggers OnNext
}
In SomeClass:
public SomeClass(ref bool value)
{
this.value = value;
}
public void OnNext(object someUpdatedValue)
{
value = true;
}
Value never becomes true and the while loop never breaks. How come? Does assigning the value property of SomeClass to the reference of value not persist?
Edit: After seeing the first two responses my new question is this:
How can I achieve this kind of behavior without using static variables?
Pass by reference affects only the variable passed as the argument to the method. In your example, the value of false, which is what the variable value contained when you assigned it to this.value, is copied to the this.value field. Nothing more.
There's nothing magical in C# that will remember where that value came from and update the variable later, when the field to which its value was assigned is changed later.
Does assigning the value property of SomeClass to the reference of value not persist?
You aren't assigning "the reference of value". All that happens when you pass by-reference is that if the local variable itself is changed, then the variable that was passed is modified. When you use the value of the variable, you're only using the value, not the reference.
EDIT:
Without more context, it's impossible to say what the best way to approach this would be. But note that reference types achieve something similar to what you seem to be trying to do. For example:
class VolatileBoolWrapper
{
public bool Value { get { return _value; } }
private volatile bool _value;
public void SetValue(bool value)
{
_value = value;
}
}
VolatileBoolWrapper value = new VolatileBoolWrapper();
provider.Subscribe(new SomeClass(value));
while (!value.Value)
{
provider.GetEvents() //triggers OnNext
}
public SomeClass(VolatileBoolWrapper value)
{
this.value = value;
}
public void OnNext(object someUpdatedValue)
{
value.SetValue(true);
}
In that way, the VolatileBoolWrapper class acts as a go-between for the caller and callee.
<edit>
Note that I marked the field as volatile, and named the class Volatile... just to be safe. There's not enough context in the question for me to know what "triggers" actually means (i.e. does the same thread actually set the value, or is this something that involves interaction between threads).
If it happens that the call to OnNext() occurs within the same thread, strictly by virtue of the call to GetEvents(), then you can omit the use of volatile here (and ignore, or at least discount, my note about polling below).
</edit>
All that said, frankly: polling on a variable like this is pretty much always the wrong way to accomplish one's goals. There have always been much better approaches for things like this, but in modern C#, I would say that TaskCompletionSource is the best alternative. Like other mechanisms that came before it, it allows your waiting code to not continually use CPU time checking to see if the event has occurred; unlike them, it also provides an excellent mechanism for allowing that entire thread to continue executing, performing other work, only resuming at the await statement where you waited for the event when that event actually occurs.
The ref modifier affects the caller, not the callee. It allows you to reassign the caller's variable to "point to" a new value. For example:
bool myValue = true;
WithoutRef_YouCannotReassign(myValue);
Console.WriteLine(myValue); // myValue is still true
WithRef_YouCanReassign(ref myValue);
Console.WriteLine(myValue); // myValue is now false
void WithoutRef_YouCannotReassign(bool value) {
value = false;
}
void WithRef_YouCanReassign(bool value) {
value = false;
}
You're trying to pass out a reference to SomeClass.value. Normally, that'd work great by just swapping your assignment (remember, you're changing the caller's variable to point at something else)
public SomeClass(ref bool value)
{
value = this.value;
}
But, you've got another problem. Since a bool is immutable - even though your caller is pointing at the right value, you point your own value to something else later by overwriting it:
public void OnNext(object someUpdatedValue)
{
value = true; // value is now pointing somewhere else! the caller never got a reference to the somewhere else!
}
So, now, you actually need a wrapper to avoid having to overwrite SomeClass.value after you passed a reference out to it:
struct MyBoolWrapper
{
public bool Value { get; set; }
}
public SomeClass(ref MyBoolWrapper value)
{
value = this.value;
}
public void OnNext(object someUpdatedValue)
{
value.Value = true;
}
Now, this won't work because it's a struct (like bool is). structs are value types, and so the value of it gets copied back. When you change SomeClass.value, you're changing a different copy again! (This is one reason we tend to prefer immutable structs, like bool is).
So, let's change this to a class:
class MyBoolWrapper
{
public bool Value { get; set; }
}
This will work as expected since you end up passing back a reference to MyBoolWrapper (which doesn't change).
So, now we're working - but let's look at some cleanup. It seems a little silly for our caller to have to new a MyBoolWrapper just so that we can point it to something else. Let's change that:
MyBoolWrapper wrapper = null;
provider.Subscribe(new SomeClass(ref wrapper));
Well, now it seems silly that we set it to null. Since SomeClass is providing all the info, let's just make it an out (which, essentially, works the same as ref just without requiring it to be initialized):
MyBoolWrapper wrapper;;
provider.Subscribe(new SomeClass(out wrapper));
Of course, now it's not even clear why we can't just hold a reference to SomeClass directly, and get rid of this whole out/ref dance:
SomeClass someClass = new SomeClass();
provider.Subscribe(someClass);
while (!someClass.Value) {
provider.GetEvents();
}
class SomeClass {
public Value { get; private set; }
public void OnNext(object someUpdatedValue)
{
Value = true;
}
}
There - that's simpler. Since the caller has a reference to our instance that changes it's state (without changing it's identity), we don't have to worry about all of that method calling by-ref/by-val struct vs class mumbo-jumbo.
This might be a trivial question but I got really confused on this. I have a property with some logic in it.
private SomeObject _someProperty;
public SomeObject SomeProperty
{
get
{
Some checking here,
return _someProperty;
}
set
{
_someProperty = value;
}
}
Now what will happen when I am going to assign something to this property.
SomeProperty = new SomeClass();
What I was thinking here that get will be called here. It words it can be said like get SomeProperty and set that property. But what I have observed is that get is not called. Only setter is called (correct me if I am wrong here). I want to know if get is not called here what is its reason.
In simpler way to think about it.
GET: When something somewhere wants to GET value from here.
SET: When something somewhere wants to SET value here.
So, getters and setters answer to question from outside perspective. When you want to write value, SET is called. When you want to know current value, GET is called.
Properties are really just syntactic sugar for get/set methods. As the C# Programming Guide says:
A property is a member that provides a flexible mechanism to read, write, or compute the value of a private field. Properties can be used as if they are public data members, but they are actually special methods called accessors. This enables data to be accessed easily and still helps promote the safety and flexibility of methods.
So your example really translates to something like:
private SomeObject _someProperty;
public SomeObject get_SomeProperty()
{
// Some checking here,
return _someProperty;
}
public void set_SomeProperty(SomeObject value)
{
_someProperty = value;
}
With the assignment becoming
set_SomeProperty(new SomeClass());
When thought of this way, it's clear that the getter is not called when you assign the property.
No, a property's getter is not called when setting the property, as can be easily demonstrated :
static class Program
{
static void Main(string[] args)
{
Foo foo = new Foo();
foo.Number = 7;
}
}
public class Foo
{
private int number;
public int Number
{
get
{
Console.WriteLine("In getter");
return this.number;
}
set
{
Console.WriteLine("In setter");
this.number = value;
}
}
}
Output:
In setter
No, get is called when you are reading the value of the property, set is called when you are assigning a value to the property.
What I was thinking here that get will be called here
Why? You are clear - you SET. And SET does not do anything in GET. Ergo, get is never called.
This IS the correct behaviour of mutator methods, you dont Read the Value from accessor
You don't need value of SomeProperty in this expression. If you wrote something like SomeProperty = SomeProperty + 1; then you will need a value of SomeProperty, and get will be called.
Actually
A property is a member that provides a flexible mechanism to read,
write, or compute the value of a private field. Properties can be used
as if they are public data members, but they are actually special
methods called accessors.
as it is said in msdn.
So consider it as a wrapper for something like this:
private SomeObject _someProperty;
public SomeObject getSomeProperty()
{
//Some checking here,
return _someProperty;
}
public void setSomeProperty(SomeObject value)
{
_someProperty = value;
}
It should be clear now unless you have the same question about setting the fields.
Is it possible to get value without creating an instance ?
I have this class:
public class MyClass
{
public string Name{ get{ return "David"; } }
public MyClass()
{
}
}
Now I need get the value "David", without creating instance of MyClass.
Real answer: no. It's an instance property, so you can only call it on an instance. You should either create an instance, or make the property static as shown in other answers.
See MSDN for more information about the difference between static and instance members.
Tongue-in-cheek but still correct answer:
Is it possible to get value without creating an instance ?
Yes, but only via some really horrible code which creates some IL passing in null as this (which you don't use in your property), using a DynamicMethod. Sample code:
// Jon Skeet explicitly disclaims any association with this horrible code.
// THIS CODE IS FOR FUN ONLY. USING IT WILL INCUR WAILING AND GNASHING OF TEETH.
using System;
using System.Reflection.Emit;
public class MyClass
{
public string Name { get{ return "David"; } }
}
class Test
{
static void Main()
{
var method = typeof(MyClass).GetProperty("Name").GetGetMethod();
var dynamicMethod = new DynamicMethod("Ugly", typeof(string),
Type.EmptyTypes);
var generator = dynamicMethod.GetILGenerator();
generator.Emit(OpCodes.Ldnull);
generator.Emit(OpCodes.Call, method);
generator.Emit(OpCodes.Ret);
var ugly = (Func<string>) dynamicMethod.CreateDelegate(
typeof(Func<string>));
Console.WriteLine(ugly());
}
}
Please don't do this. Ever. It's ghastly. It should be trampled on, cut up into little bits, set on fire, then cut up again. Fun though, isn't it? ;)
This works because it's using call instead of callvirt. Normally the C# compiler would use a callvirt call even if it's not calling a virtual member because that gets null reference checking "for free" (as far as the IL stream is concerned). A non-virtual call like this doesn't check for nullity first, it just invokes the member. If you checked this within the property call, you'd find it's null.
EDIT: As noted by Chris Sinclair, you can do it more simply using an open delegate instance:
var method = typeof(MyClass).GetProperty("Name").GetGetMethod();
var openDelegate = (Func<MyClass, string>) Delegate.CreateDelegate
(typeof(Func<MyClass, string>), method);
Console.WriteLine(openDelegate(null));
(But again, please don't!)
You can make that property static
public static string Name{ get{ return "David"; } }
Usage:
MyClass.Name;
You requirements do seem strange, but I think you're looking for some kind of metadata. You can use an attribute to achieve this:
public class NameAttribute : Attribute {
public string Name { get; private set; }
public NameAttribute(string name) {
Name = name;
}
}
[Name("George")]
public class Dad {
public string Name {
get {
return NameGetter.For(this.GetType());
}
}
}
[Name("Frank")]
public class Son : Dad {
}
public static class NameGetter {
public static string For<T>() {
return For(typeof(T));
}
public static string For(Type type) {
// add error checking ...
return ((NameAttribute)type.GetCustomAttributes(typeof(NameAttribute), false)[0]).Name;
}
}
Now this code can get names with and without instances:
Console.WriteLine(new Dad().Name);
Console.WriteLine(new Son().Name);
Console.WriteLine(NameGetter.For<Dad>());
Console.WriteLine(NameGetter.For<Son>());
You can make your property static, as pointed out by many others.
public static string Name{ get{ return "David"; } }
Be aware that this means your instances of MyClass will no longer have their own Name property, since static members belong to the class, not the individual object instances of it.
Edit:
In a note, you mentioned that you want to override the Name property in subclasses. At the same time, you want to be able to access it at the class level (access it without creating an instance of your class).
For the static properties, you would simply create a new Name property in each class. Since they are static, you're always (almost always, yay reflection) going to access them using a specific class, so you'd be specifying which version of Name you want to get. If you want to try and hack polymorphism in there and get the name from any given subclass of MyClass, you could do so using reflection, but I wouldn't recommend doing so.
Using the example from your comment:
public class Dad
{
public static string Name { get { return "George"; }
}
public class Son : Dad
{
public static string Name { get{ return "Frank"; }
}
public static void Test()
{
Console.WriteLine(Dad.Name); // prints "George"
Console.WriteLine(Son.Name); // prints "Frank"
Dad actuallyASon = new Son();
PropertyInfo nameProp = actuallyASon.GetType().GetProperty("Name");
Console.WriteLine(nameProp.GetValue(actuallyASon, null)); // prints "Frank"
}
As a side note, since you are declaring a property that has only a getter and it is returning a constant value, I recommend possibly using a const or static readonly variable instead.
public const string Name = "David";
public static readonly string Name = "David";
Usage for both would be the same:
string name = MyClass.Name;
The main benefit (and drawback) of const is that all references to it are actually replaced by its value when the code is compiled. That means it will be a little faster, but if you ever change its value, you will need to recompile ALL code that references it.
Whenever you write C# code, always check if your method and property getter/setter code does anything at all with other instance members of the class. If they don't, be sure to apply the static keyword. Certainly the case here, it trivially solves your problem.
The reason I really post to this question is that there's a bit of language bias at work in some of the answers. The C# rule that you can't call an instance method on a null object is a specific C# language rule. It is without a doubt a very wise one, it really helps to troubleshoot NullReferenceExceptions, they are raised at the call site instead of somewhere inside of a method where it gets very hard to diagnose that the this reference is null.
But this is certainly not a requirement to the CLR, nor of every language that run on the CLR. In fact, even C# doesn't enforce it consistently, you can readily bypass it in an extension method:
public static class Extensions {
public static bool IsNullOrEmpty(this string obj) {
return obj != null && obj.Length > 0;
}
}
...
string s = null;
bool empty = s.IsNullOrEmpty(); // Fine
And using your property from a language that doesn't have the same rule works fine as well. Like C++/CLI:
#include "stdafx.h"
using namespace System;
using namespace ClassLibrary1; // Add reference
int main(array<System::String ^> ^args)
{
MyClass^ obj = nullptr;
String^ name = obj->Name; // Fine
Console::WriteLine(name);
return 0;
}
Create a static property:
public class MyClass
{
public static string Name { get { return "David"; } }
public MyClass()
{
}
}
Get it like so:
string name1 = MyClass.Name;
That is not possible. As Name is an instance property, you can only get its value if you have an instance.
Also, note that you are not talking about a parameter, but about a property.
Create a static class or a static property, and you don't have to explicitly instantiate it.
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);