I'm trying to get and set a property using the following code.
But the when trying to print the property using Console,it returns an empty string.Why is the property not getting set?
using System;
public class Program
{
public static void Main()
{
myclass x=new myclass();
x.myproperty="test";
Console.WriteLine(x.myproperty);
}
class myclass{
string sample;
public string myproperty
{
get { return sample;}
set {sample=myproperty;}
}
}
}
In setter you should use value to assign new value to underlying field
use this instead
public string myproperty
{
get { return sample; }
set { sample = value; }
}
or in C#7
public string myproperty
{
get => sample;
set => sample = value;
}
Edit
As #bradbury9 mentioned, you can also use auto-implemented properties, of course this is the case if you don't want any other logic in getter and setter than just getting and setting the field, if this is the case you can use below snippet
public string myproperty { get; set; }
value keyword is important for setting the value. In Visual Studio you can use propfull + double tab to avoid such common mistakes. It will create full property through shortcuts.
Here is the solution
public static void Main()
{
myclass x = new myclass();
x.myproperty = "test";
Console.WriteLine(x.myproperty);
}
class myclass
{
string sample;
public string myproperty
{
get { return sample; }
set { sample = value; }
}
}
If you just want to return null instead of empty string. This works even when you deserialize your Json:
class myclass
{
string sample;
[JsonProperty("my_property")]
public string My_property
{
get { return sample; }
set { sample = string.IsNullOrEmpty(value) ? null : value; }
}
}
I am trying to use setter and getter. When i debug, the value gets set but when i try to retrieve, it gets null value.
Class1.cs
private string setMAX;
public string SETMax
{
get
{
return setMAX;
}
set
{
setMAX = value;
}
}
private string value1;
public string MaxValue
{
get
{
return value1;
}
set
{
value1= value;
}
}
Class2.cs
Class1.SETMax = Class1.value1; //This gets set
Class3.cs
//When i debug, first Class1.cs and Class2.cs completes, then it comes in Class3.cs
string max = Class1.SETMax; //I GET NULL here.
I dont know where I am wrong here.Can anyone please explain me ?
You are referencing File1 as an instance. You are probably referencing different instances. You probably want static properties.
private static string setMAX;
public static string SETMax
{
get
{
return setMAX;
}
set
{
setMAX = value;
}
}
I think you have a few things mixed up so lets start from the beginning
Class1.SETMax = Class1.value1;
// for a start you are assigning a
// private variable to a public one
// via the Class definition I'm not even sure how that compiles.
Have a look here see if this makes sense to you
// This is a Class definition
public class Class1 {
public string SETMax {get; set;}
public int MaxValue {get; set;}
}
// This is your application
public class MyApp{
// this is a private field where you will assign an instance of Class1
private Class1 class1Instance ;
public MyApp(){
//assign the instance in the constructor
class1Instance = new Class1();
}
public void Run {
// now for some fun
class1Instance.SETMax = "Hello";
Console.WriteLine(class1Instance.SETMax); // outputs "Hello"
var localInstance = new Class1();
localInstance.SETMax = class1Instance.SETMax;
Console.WriteLine(localInstance.SETMax); // outputs "Hello"
}
}
Is there a way to dynamically identify design time properties in C#? For example:
class MyClass
{
public string MyProperty1 { get; set; }
}
And then reference it something like this:
string myVar = "MyProperty1";
MyClass.myVar = "test";
If you want to set the value of a property at runtime and the name of the property is only known at runtime you need to use Reflection. Here's an example:
public class MyClass
{
public string MyProperty1 { get; set; }
}
class Program
{
static void Main()
{
// You need an instance of a class
// before being able to set property values
var myClass = new MyClass();
string propertyName = "MyProperty1";
// obtain the corresponding property info given a property name
var propertyInfo = myClass.GetType().GetProperty(propertyName);
// Before trying to set the value ensure that a property with the
// given name exists by checking for null
if (propertyInfo != null)
{
propertyInfo.SetValue(myClass, "test", null);
// At this point you've set the value of the MyProperty1 to test
// on the myClass instance
Console.WriteLine(myClass.MyProperty1);
}
}
}
how about simply implementing an indexer on your class
public class MyClass
{
public string MyProperty1 { get; set; }
public object this[string propName]
{
get
{
return GetType().GetProperty(propName).GetValue(this, null);
}
set
{
GetType().GetProperty(propName).SetValue(this, value, null);
}
}
}
and then you can do something very similar
var myClass = new MyClass();
string myVar = "MyProperty1";
myClass[myVar] = "test";
Yes, of course you can. You need to get a FieldInfo object relating to the property that you want to set.
var field = typeof(MyClass).GetField("MyProperty1");
then from that field info object, you can set the value of any instance of that class.
field.SetValue(myinstanceofmyclass, "test");
See MSDN: FieldInfo for other fun stuff you can do with reflection.
class CustomerMessage
{
private string name;
private Dictionary<MethodBase, object> changeTrackingMethods =
new Dictionary<MethodBase, object>();
public int Id { get; set; }
public string Name {
get { return this.name; }
set
{
this.name = value;
this.PropertyChanged("SetName", value);
}
}
private void PropertyChanged(string behaviorMethod, object value)
{
var method = typeof(Customer).GetMethod(behaviorMethod);
this.changeTrackingMethods.Add(method, value);
}
public void ApplyChanges(Customer c)
{
foreach (var changedProperty in this.changeTrackingMethods)
changedProperty.Key.Invoke(c, new object[] {
changedProperty.Value
});
}
}
As you can see I am tracking the changes on this incoming message, to run the changes on another object. The method to run is passed to PropertyChanged as a string. Does anyone have a tip how I can make this type safe?
Something like this?
class CustomerMessage
{
private string name;
private List<Action<Customer>> changeTrackingMethods =
new List<Action<Customer>>();
public int Id { get; set; }
public string Name {
get { return this.name; }
set
{
this.name = value;
this.changeTrackingMethods.Add(c => { c.SetName(value) });
}
}
public void ApplyChanges(Customer c)
{
foreach (var action in this.changeTrackingMethods)
{
action(c);
}
}
}
So you want to avoid passing the method name as a string? Why not get the MethodBase object in the setter?
public string Name {
get { return this.name; }
set
{
this.name = value;
this.PropertyChanged(typeof(Customer).GetMethod(behaviorMethod), value);
}
}
private void PropertyChanged(MethodBase method, object value)
{
this.changeTrackingMethods.Add(method, value);
}
Instead of storing the "operation that needs to be done" as a pair of method and an argument that should be passed to it using Reflection, you can store a delegate that should be executed. The simplest way to do this is to store a list of type List<Action<Customer>> - then in the ApplyChanges method, you can iterate over the list and run all the actions.
In case you're not using .NET 3.5 and C# 3.0 (which defines a generic delegate Action and supports lambda expressions), you can still write this in C# 2.0:
// you can define a delegate like this
delegate void UpdateCustomer(Customer c);
// and you could use anonymous methods
// (instead of more recent lambda expressions)
list.Add(delegate (Customer c) { c.SetName("test"); });
EDIT: It looks like I was slower with writing the code, but I'll keep this here as an explanation - the solution by 'dtb' does exactly what I described.
I've created a class with properties that have default values. At some point in the object's lifetime, I'd like to "reset" the object's properties back to what they were when the object was instantiated. For example, let's say this was the class:
public class Truck {
public string Name = "Super Truck";
public int Tires = 4;
public Truck() { }
public void ResetTruck() {
// Do something here to "reset" the object
}
}
Then at some point, after the Name and Tires properties have been changed, the ResetTruck() method could be called and the properties would be reset back to "Super Truck" and 4, respectively.
What's the best way to reset the properties back to their initial hard-coded defaults?
You can have the initialization in a method instead of inlining with the declaration. Then have the constructor and reset method call the initialization method:
public class Truck {
public string Name;
public int Tires;
public Truck() {
Init();
}
public void ResetTruck() {
Init();
}
private void Init() {
Name = "Super Truck";
Tires = 4;
}
}
Another way is not to have a reset method at all. Just create a new instance.
Reflection is your friend. You could create a helper method to use Activator.CreateInstance() to set the default value of Value types and 'null' for reference types, but why bother when setting null on a PropertyInfo's SetValue will do the same.
Type type = this.GetType();
PropertyInfo[] properties = type.GetProperties();
for (int i = 0; i < properties.Length; ++i)
properties[i].SetValue(this, null); //trick that actually defaults value types too.
To extend this for your purpose, have private members:
//key - property name, value - what you want to assign
Dictionary<string, object> _propertyValues= new Dictionary<string, object>();
List<string> _ignorePropertiesToReset = new List<string>(){"foo", "bar"};
Set the values in your constructor:
public Truck() {
PropertyInfo[] properties = type.GetProperties();
//exclude properties you don't want to reset, put the rest in the dictionary
for (int i = 0; i < properties.Length; ++i){
if (!_ignorePropertiesToReset.Contains(properties[i].Name))
_propertyValues.Add(properties[i].Name, properties[i].GetValue(this));
}
}
Reset them later:
public void Reset() {
PropertyInfo[] properties = type.GetProperties();
for (int i = 0; i < properties.Length; ++i){
//if dictionary has property name, use it to set the property
properties[i].SetValue(this, _propertyValues.ContainsKey(properties[i].Name) ? _propertyValues[properties[i].Name] : null);
}
}
Unless creating the object is really expensive (and Reset isn't for some reason). I see no reason to implement a special reset method. Why don't you just create a new instance with a usable default state.
What is the purpose of reusing the instance?
If you did your initialization in a Reset method you can be good to go:
public class Truck {
public string Name;
public int Tires;
public Truck() {
ResetTruck();
}
public void ResetTruck() {
Name = "Super Truck";
Tires = 4;
}
}
Focusing of separation of concerns (like Brian mentioned in the comments), another alternative would be to add a TruckProperties type (you could even add your default values to its constructor):
public class TruckProperties
{
public string Name
{
get;
set;
}
public int Tires
{
get;
set;
}
public TruckProperties()
{
this.Name = "Super Truck";
this.Tires = 4;
}
public TruckProperties(string name, int tires)
{
this.Name = name;
this.Tires = tires;
}
}
Inside your Truck class, all you would do is manage an instance of the TruckProperties type, and let it do its reset.
public class Truck
{
private TruckProperties properties = new TruckProperties();
public Truck()
{
}
public string Name
{
get
{
return this.properties.Name;
}
set
{
this.properties.Name = value;
}
}
public int Tires
{
get
{
return this.properties.Tires;
}
set
{
this.properties.Tires = value;
}
}
public void ResetTruck()
{
this.properties = new TruckProperties();
}
}
This certainly may be a lot of (unwanted) overhead for such a simple class, but in a bigger/more complex project it could be advantageous.
That's the thing about "best" practices... a lot of times, there's no silver bullet, but only recommendations you must take with skepticism and your best judgement as to what applies to you in a particular case.
I solved a similar problem with reflection. You can use source.GetType().GetProperties() to get a list of all properties which belong to the object.
Although, this is not always a complete solution. If your object implements several interfaces, you will also get all those properties with your reflection call.
So I wrote this simple function which gives us more control of which properties we are interested in resetting.
public static void ClearProperties(object source, List<Type> InterfaceList = null, Type SearchType = null)
{
// Set Interfaces[] array size accordingly. (Will be size of our passed InterfaceList, or 1 if InterfaceList is not passed.)
Type[] Interfaces = new Type[InterfaceList == null ? 1 : InterfaceList.Count];
// If our InterfaceList was not set, get all public properties.
if (InterfaceList == null)
Interfaces[0] = source.GetType();
else // Otherwise, get only the public properties from our passed InterfaceList
for (int i = 0; i < InterfaceList.Count; i++)
Interfaces[i] = source.GetType().GetInterface(InterfaceList[i].Name);
IEnumerable<PropertyInfo> propertyList = Enumerable.Empty<PropertyInfo>();
foreach (Type face in Interfaces)
{
if (face != null)
{
// If our SearchType is null, just get all properties that are not already empty
if (SearchType == null)
propertyList = face.GetProperties().Where(prop => prop != null);
else // Otherwise, get all properties that match our SearchType
propertyList = face.GetProperties().Where(prop => prop.PropertyType == SearchType);
// Reset each property
foreach (var property in propertyList)
{
if (property.CanRead && property.CanWrite)
property.SetValue(source, null, new object[] { });
}
}
else
{
// Throw an error or a warning, depends how strict you want to be I guess.
Debug.Log("Warning: Passed interface does not belong to object.");
//throw new Exception("Warning: Passed interface does not belong to object.");
}
}
}
And it's use:
// Clears all properties in object
ClearProperties(Obj);
// Clears all properties in object from MyInterface1 & MyInterface2
ClearProperties(Obj, new List<Type>(){ typeof(MyInterface1), typeof(MyInterface2)});
// Clears all integer properties in object from MyInterface1 & MyInterface2
ClearProperties(Obj, new List<Type>(){ typeof(MyInterface1), typeof(MyInterface2)}, typeof(int));
// Clears all integer properties in object
ClearProperties(Obj,null,typeof(int));
You'd probably need to save the values off in private fields, so that they can be restored later. Maybe something like this:
public class Truck
{
private static const string defaultName = "Super Truck";
private static const int defaultTires = 4;
// Use properties for public members (not public fields)
public string Name { get; set; }
public int Tires { get; set; }
public Truck()
{
Name = defaultName;
Tires = defaultTires;
}
public void ResetTruck()
{
Name = defaultName;
Tires = defaultTires;
}
}
You're essentially looking for the State Design Pattern
If you want a specific past "state" of your object you can create a particular save point to return every time you want. This also let you have a diferent state to backup for everey instance that you create. If you class has many properties who are in constant change, this could be your solution.
public class Truck
{
private string _Name = "Super truck";
private int _Tires = 4;
public string Name
{
get { return _Name; }
set { _Name = value; }
}
public int Tires
{
get { return _Tires; }
set { _Tires = value; }
}
private Truck SavePoint;
public static Truck CreateWithSavePoint(string Name, int Tires)
{
Truck obj = new Truck();
obj.Name = Name;
obj.Tires = Tires;
obj.Save();
return obj;
}
public Truck() { }
public void Save()
{
SavePoint = (Truck)this.MemberwiseClone();
}
public void ResetTruck()
{
Type type = this.GetType();
PropertyInfo[] properties = type.GetProperties();
for (int i = 0; i < properties.Count(); ++i)
properties[i].SetValue(this, properties[i].GetValue(SavePoint));
}
}
If you aren't using a Code Generator or a Designer that would conflict, another option is to go through C#'s TypeDescriptor stuff, which is similar to Reflection, but meant to add more meta information to a class than Reflection could.
using System.ComponentModel;
public class Truck {
// You can use the DefaultValue Attribute for simple primitive properites
[DefaultValue("Super Truck")]
public string Name { get; set; } = "Super Truck";
// You can use a Reset[PropertyName]() method for more complex properties
public int Tires { get; set; } = 4;
public void ResetTires() => Tires = 4;
public Truck() { }
public void ResetTruck() {
// Iterates through each property and tries to reset it
foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(GetType())) {
if (prop.CanResetValue(this)) prop.ResetValue(this);
}
}
}
Note that ResetValue will also reset to a shadowed property if one exists. The priority of which option is selected is explained in the docs:
This method determines the value to reset the property to in the following order of precedence:
There is a shadowed property for this property.
There is a DefaultValueAttribute for this property.
There is a "ResetMyProperty" method that you have implemented, where "MyProperty" is the name of the property you pass to it.
You may represent an object state as a struct or record struct and then set the state to the default value in the Reset method like this:
public class Truck {
record struct State(string Name, int Tires);
private static readonly State _defaultState = new("Super Truck", 4);
private State _state = _defaultState;
public string Name => _state.Name;
public int Tires => _state.Tires;
public Truck() {}
public void ResetTruck() => _state = _defaultState;
}
It is probably the fastest way as well.
Also, a record struct will give you the trivial implementations of the ToString, Equals, GetHashCode.