My CTO (Chief Technical Officer) asked me to come up with a way where he could write one single function in the base class, and have access to the all the properties of the child class. Here is what I came up with -
Base Class
class Assets
{
public Assets getPropertyVal(Assets asObj)
{
PropertyInfo[] propInfos = asObj.GetType().GetProperties();
string strAttributeValue = "10";
foreach (PropertyInfo propInfo in propInfos)
{
// Getting the value
var propValue = propInfo.GetValue(asObj, null);
// Setting the value
propInfo.SetValue(asObj, Convert.ChangeType(strAttributeValue, propInfo.PropertyType), null);
}
return asObj;
}
}
Child Class
class House : Assets
{
public int rooms{get; set;}
}
Program.cs file
class Program
{
static void Main(string[] args)
{
House hsObj = new House();
hsObj.rooms = 5;
Assets asObj = hsObj.getPropertyVal(hsObj);
// Returns asObj as JSON
}
}
Now this works fine, but I was just wondering if there was a better way to do this in C#.
Note that we do not know what properties will be present in the child class, so this will have to be determined at run-time.
UPDATE : Making it clear, I was just wondering if there is a better way to access the child class properties, one without using reflection. The important point to note is that we have no idea what properties a child class may have.
UPDATE #2 : I am working with a product that has many entities. These entities have different properties. I want to be able to access and work with all these properties in one single place. This function is exactly that. It's that one single place from where I can access all the data.
First, your Program.cs doesn't actually "do" what you say you want. It sounds like you want a program so that you can do this:
Asset myAsset = new House();
myAsset.Rooms = 5;
But, why would you even want to do that anyway? If your asset isn't a House, it will throw an exception, so you will need to check that first:
if (myAsset is House)
myAsset.Rooms = 5;
At that point, you might as well just cast it to a House though. It sounds like you may want to use a PropertyBag or Dictionary instead of inheritance.
I think what you are describing is this. Note that option 1 doesn't really restrict which properties can be used on which classes, so I'm guessing this won't really work for your specific case.
// Option 1, a Property Bag (Note: this replaces the properties on the classes)
class Asset
{
Dictionary<string, object> myPropertyBag = new Dictionary<string, object>();
public T GetProperty<T>(string property)
{
// This throws if the property doesn't exist
return (T)myPropertyBag[property];
}
public void SetProperty<T>(string property, T value)
{
// This adds the property if it doesn't exist
myPropertyBag[property] = (object)value;
}
}
// Option 2, use a switch and override this function in derived classes
class Asset
{
public int SomePropertyOnAsset { get; set; }
public virtual T GetProperty<T>(string property)
{
switch (property)
{
case "SomePropertyOnAsset": return this.SomePropertyOnAsset;
default: throw new ArgumentException("property");
}
}
public virtual void SetProperty<T>(string property, T value)
{
switch (property)
{
case "SomePropertyOnAsset": this.SomePropertyOnAsset = (int)value;
default: throw new ArgumentException("property");
}
}
}
class House : Asset
{
public int Rooms { get; set; }
public virtual T GetProperty<T>(string property)
{
switch (property)
{
case "Rooms": return this.Rooms;
default: return base.GetProperty<T>(property);
}
}
public virtual void SetProperty<T>(string property, T value)
{
switch (property)
{
case "Rooms": this.Rooms = (int)value;
break;
default: base.SetProperty<T>(property, value);
break;
}
}
}
Then, this is how you use them:
// Option 1
Asset asset = new House();
asset.SetProperty("Rooms", 5);
var rooms = asset.GetProperty<int>("Rooms");
// Option 2
Asset asset = new House();
asset.SetProperty("Rooms", 5);
asset.SetProperty("SomePropertyOnAsset", 10);
asset.SetProperty("SomethingElse", 15); // Throws ArgumentException
A 3rd option is to make Asset a DynamicObject.
http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx
If you can't or don't want to make a major change to your Asset base class or touch every entity, you will probably need to use reflection.
Luke Gravitt is probably right. You might just want to cast it to a house.
House myHouse = asObj as House;
if ( myHouse != null )
{
// do some fun house stuff
}
Yacht myYacht = asObj as Yacht;
if ( myYacht != null )
{
// put on monocle
}
Related
I've created a data class that I plan to use to send data to be persisted in the database and to return data from the database in a strongly typed way. In addition to its properties, the class contains a Dictionary that I populate in the constructor with the name of and reference to each property. This makes the properties enumerable and enables me to iterate through them using 'foreach'.
This works great when setting property values and sending the object to be persisted in the database. I can iterate through the Dictionary keys, get the value of each property, and add a SqlParameter for each property using the key as the parameter name and the property value as the parameter value.
However, going the other way doesn't work. I can iterate through the Dictionary keys and get the value of each column in each row of the SqlDataReader, but when I try to assign these values to my data object using the Dictionary's reference to the corresponding object property, a curious thing occurs. The assignments succeed, BUT the data object properties all retain their initial, default values. I can view the data object properties and see these initial, default values. I can also view the Dictionary entry values and see the updated values that were read and assigned from the SqlDataReader.
This makes no sense. The Dictionary is supposed to provide access to each property (the 'object' generic type) via its key (the 'string' generic type), but its acting like its maintaining a separate copy of each Dictionary 'KeyValuePair'.
What gives?
I'm doing all this in C# in the context of an ASP.NET Core 2.1.1 project running on macOS 10.13.6 High Sierra.
I've searched StackOverflow extensively, and I see lots of recommendations for using reflection to do this type of thing. I'll refactor my code to use reflection if necessary, but I'd really like to understand where and how my mental model for what's happening is off.
An explanation of what's happening and why would be MOST appreciated.
Example Data Class with Property Dictionary
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Newtonsoft.Json;
namespace MyOrg.MyProj.Data
{
[DataContract]
public class DataObj
{
#region Attributes
[Required]
[DataMember(Name = "dataObjectId")]
public Int64 DataObjectId { get; set; }
[Required]
[DataMember(Name = "guid")]
public Guid Guid { get; set; }
public virtual Dictionary<string, object> DataMembers { get; set; } //NOTE: Implements the IEnumerable interface in order to support 'foreach' operations, etc on 'DataObj' class attributes
#endregion Attributes
#region Constructors
public DataObj(Int64 dataObjectId, Guid guid)
{
try
{
DataObjectId = dataObjectId;
Guid = guid;
DataMembers = new Dictionary<string, object>
{
{ "DataObjectId", DataObjectId },
{ "Guid", Guid }
};
}
catch (Exception e)
{
Console.WriteLine($"RUNTIME EXCEPTION while INSTANTIATEing DataObj, " + e.Message + ", " + e.StackTrace);
}
}
#endregion Constructors
#region Methods
/// <summary>
/// Implements the IEnumerable interface in order to support 'foreach' operations, etc on 'DataObj' class attributes
/// </summary>
/// <returns>Enumerator</returns>
public Dictionary<string, object>.Enumerator Enumerator()
{
return DataMembers.GetEnumerator(); //NOTE: Return the Dictionary object's IEnumerator rather than implementing IEnumerable for the 'DataObj' class itself
}
#endregion Methods
Example Data Access Class (excerpt)
reader = command.ExecuteReader();
dataObjList = new List<DataObj>();
if (reader.HasRows)
{
while (reader.Read())
{
tempDataObj = new DataObj(-1, new Guid("00000000-0000-0000-0000-000000000000"));
keys = new List<String>(tempDataObj.DataMembers.Keys); //NOTE: Can't modify a Dictionary while iterating through it. See the 'Why This Error?' section of https://stackoverflow.com/questions/604831/collection-was-modified-enumeration-operation-may-not-execute
foreach (String key in keys)
{
tempDataObj.DataMembers[key] = reader[key];
}
dataObjList.Add(tempDataObj);
For 'key' = 'DataObjectId', 'Guid', etc, I expect the value of tempDataObj.DataObjectId, tempDataObj.Guid, etc to be set to the value returned from the database in 'reader[key]'.
Instead, it retains its initial, default value as set in the constructor, i.e. '-1'. This is true for both value and reference data types.
However, when I inspect tempDataObj.DataMembers["DataObjectId"], it has been set to the value returned from the database in 'reader[key]'.
Inspecting the Object Property and Dictionary Values
tempDataObj.DataMembers["DataObjectId"] should be referencing the tempDataObj.DataObjectId property, etc, but the Dictionary appears to be maintaining its own value rather than providing an object reference to the 'DataObjectId' property.
What's going on here? Thank you!
You're storing the data twice - once in a Dictionary, and a second time in a field. There's no need to store it twice. Just do this:
[DataContract]
public class DataObj
{
[Required]
[DataMember(Name = "dataObjectId")]
public Int64 DataObjectId
{
get => (long)DataMembers[nameof(DataObjectId)];
set => DataMembers[nameof(DataObjectId)] = value;
}
[Required]
[DataMember(Name = "guid")]
public Guid Guid
{
get => (Guid)DataMembers[nameof(Guid)];
set => DataMembers[nameof(Guid)] = value;
}
public Dictionary<string, object> DataMembers { get; } = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
public DataObj(Int64 dataObjectId, Guid guid)
{
DataObjectId = dataObjectId;
Guid = guid;
}
public Dictionary<string, object>.Enumerator Enumerator()
{
return DataMembers.GetEnumerator();
}
}
FYI, you can also look at using an ExpandoObject, which lets you access something in a way that looks like a class, but is really just a Dictionary. https://learn.microsoft.com/en-us/dotnet/api/system.dynamic.expandoobject?view=netframework-4.7.2
I have never used an ExpandoObject and I think the whole idea is as perverse as VBA's default of option explicit being off and On Error Resume Next. On the other hand, I don't deal with databases much.
I see two (main) routes to do what you want. In both cases you should implement a custom indexer.
In the indexer explicitly check the name given to it and get or set the field or property accordingly.
Use reflection, i.e. GetField() or GetProperty(), to get the field or property and GetValue() or SetValue() to get or set the values.
Below is a demonstration where ExposeByExplicitIndexer0 and its descendants use way 1 and ExposeByIndexerUsingReflection0 and its descendants use way 2.
public class ExposeByExplicitIndexer0
{
public int Int0 = 1;
public string String0 = "A";
public virtual object this[string name]
{
get
{
switch (name)
{
case "Int0":
return this.Int0;
case "String0":
return this.String0;
default:
throw new IndexOutOfRangeException();
}
}
set
{
switch (name)
{
case "Int0":
this.Int0 = (int)value;
break;
case "String0":
this.String0 = (string)value;
break;
default:
throw new IndexOutOfRangeException();
}
}
}
}
public class ExposeByExplicitIndexer1 : ExposeByExplicitIndexer0
{
protected Guid _Guid1 = Guid.Empty;
public Guid Guid1
{
get
{
return this._Guid1;
}
set
{
this._Guid1 = value;
}
}
public override object this[string name]
{
get
{
switch (name)
{
case "Guid1":
return this.Guid1;
default:
return base[name];
}
}
set
{
switch (name)
{
case "Guid1":
this.Guid1 = (Guid)value;
break;
default:
base[name] = value;
break;
}
}
}
}
public class ExposeByIndexerUsingReflection0
{
public object this[string name]
{
get
{
FieldInfo fieldInfo;
if ((fieldInfo = this.GetType().GetField(name)) != null)
{
return fieldInfo.GetValue(this);
}
PropertyInfo propertyInfo;
if ((propertyInfo = this.GetType().GetProperty(name)) != null)
{
return propertyInfo.GetValue(this);
}
throw new IndexOutOfRangeException();
}
set
{
FieldInfo fieldInfo;
if ((fieldInfo = this.GetType().GetField(name)) != null)
{
fieldInfo.SetValue(this, value);
return;
}
PropertyInfo propertyInfo;
if ((propertyInfo = this.GetType().GetProperty(name)) != null)
{
propertyInfo.SetValue(this, value);
return;
}
throw new IndexOutOfRangeException();
}
}
}
public class ExposeByIndexerUsingReflection1 : ExposeByIndexerUsingReflection0
{
public int Int1 = 1;
public string String1 = "A";
}
public class ExposeByIndexerUsingReflection2 : ExposeByIndexerUsingReflection1
{
protected Guid _Guid2 = Guid.Empty;
public Guid Guid2
{
get
{
return this._Guid2;
}
set
{
this._Guid2 = value;
}
}
}
public class Program
{
static void Main(string[] args)
{
Guid newGuid = Guid.NewGuid();
Console.WriteLine("Expose by explicit indexer:");
ExposeByExplicitIndexer1 exposeByExplicitIndexer1 = new ExposeByExplicitIndexer1();
exposeByExplicitIndexer1["Int0"] = 10;
exposeByExplicitIndexer1["String0"] = "AAA";
exposeByExplicitIndexer1["Guid1"] = newGuid;
Console.WriteLine("output via indexer:");
Console.WriteLine(exposeByExplicitIndexer1["Int0"]);
Console.WriteLine(exposeByExplicitIndexer1["String0"]);
Console.WriteLine(exposeByExplicitIndexer1["Guid1"]);
Console.WriteLine("output via fields or properties:");
Console.WriteLine(exposeByExplicitIndexer1.Int0);
Console.WriteLine(exposeByExplicitIndexer1.String0);
Console.WriteLine(exposeByExplicitIndexer1.Guid1);
Console.WriteLine("Expose by indexer using reflection:");
ExposeByIndexerUsingReflection2 exposeByIndexerUsingReflection2 = new ExposeByIndexerUsingReflection2();
exposeByIndexerUsingReflection2["Int1"] = 10;
exposeByIndexerUsingReflection2["String1"] = "AAA";
exposeByIndexerUsingReflection2["Guid2"] = newGuid;
Console.WriteLine("output via indexer:");
Console.WriteLine(exposeByIndexerUsingReflection2["Int1"]);
Console.WriteLine(exposeByIndexerUsingReflection2["String1"]);
Console.WriteLine(exposeByIndexerUsingReflection2["Guid2"]);
Console.WriteLine("output via fields or properties:");
Console.WriteLine(exposeByIndexerUsingReflection2.Int1);
Console.WriteLine(exposeByIndexerUsingReflection2.String1);
Console.WriteLine(exposeByIndexerUsingReflection2.Guid2);
Console.Read();
}
}
In way 1 every descendant that adds new fields or properties has to extend the indexer. That's more work in general but also offers an easy way of flexibility i.e. for adding some casts or expose some field or property via an alias, etc.
Way 2 needs less effort in the descendants. But being as flexible as in way 1 may become more difficult in turn. Maybe some mixed solution is also possible overriding the indexer in some descendant to inject special logic.
I have an ASP.NET MVC (Not Core) project where I have run into some problems, and I think finally getting around to learning how to properly use generics could be a solution to my problems.
My case is that I have a SQL connection, that returns data and depending on the result of one field in the SQL, I want to use two different models. The models have a lot of properties in common so I thought the best practice would be to create a method that selects which of the models to create, fill in the differences, return the model and then continue to fill in the "common" properties.
I have tried to read a little on Generics but I am quite new to this so I haven't made any big strides.
My code example looks like this:
public ResultVM MainClass()
{
var resultData = new ResultVM();
// ... SQL returns data
while (reader.Read())
{
resultData.Add(reader);
}
return resultData;
}
public object CreateObject(SqlDataReader indata)
{
if((indata["Associate"].ToString()) == "0")
{
var individual = new Individual();
}
else
{
var group = new Group();
}
return object;
}
How can I dynamically (depending on the value of Associate field) create an individual or a group?
I suggest working directly with System.Type in your case. Here can be multiple more elegant solutions of your problem, depending of what you actually need:
indata.GetFieldType(int ordinal) will return the .NET type of your field
Serialize data with type handling, then you can simply get type after non generic deserialization. For example:
var result = JsonConvert.DeserializeObject(dataJson);
result will have Type of your actual object type. You can check it writing result.GetType() and create an object of this type. For more advanced use see Activator.CreateInstance(...)
For the most cases using interface is the best way:
interface ISomething
{
// ...
}
class Individual : ISomething
{
// ...
}
class Group : ISomething
{
// ...
}
Then you cat build your non generic method this way:
public ISomething CreateObject(SqlDataReader indata)
{
if((indata["Associate"].ToString()) == "0")
return new Individual();
else
return new Group();
}
Your generic object creation may look something like this:
public T CreateObject<T>(SqlDataReader indata)
{
var o = new T();
return o;
}
Where T is type, that you pass outside this method: CreateObject<YourType>(indata)
T can be any Type you want including Interfaces. Also working with generics you may want check types by using is keyword, but I recommend using interfaces and avoid is checks at all.
Example:
if(yourObject is YourType)
{
(yourObject as YourType).SomeSpecificToYourTypeMethod();
// ...
}
What about implementing an interface with all the common properties?
Something like
interface IInterface
{
string CommonProperty1 { get; set; }
string CommonProperty2 { get; set; }
}
class Individual : IInterface
{
// ...
}
class Group : IInterface
{
// ...
}
public IInterface CreateObject(SqlDataReader indata)
{
if((indata["Associate"].ToString()) == "0")
{
var individual = new Individual();
// ...
return individual;
}
else
{
var group = new Group();
// ...
return group;
}
}
Hi I have an abstract class Item. Classes like Food, Weapon, etc inherit by this class. All informations about this items are stored in the database, work of C# Code is match the exact class and match it by Enum which is also stored in the database column as integer. My problem is this stupid code wherever I have to use methods of Food, Weapon etc classes
if ((ItemType)userItem.ItemType == ItemType.Food)
{
Food food = new Food(userItem);
food.UseItem(sender);
}
else if ((ItemType)userItem.ItemType == ItemType.Weapon)
{
Weapon weapon = new Weapon(userItem);
weapon.UseItem(sender);
}
In the parameter of constructor of Food, Weapon etc. classes is the the object from database to let know object about its fields.
Is some kind of stuff that will help me to match this types without this code? It really annoys me when I'm looking at it.
You can use factory or creational method to create specific type of item:
public Item CreateItem(UserItem userItem)
{
var itemType = (ItemType)userItem.ItemType;
switch(itemType)
{
case ItemType.Food: return new Food(userItem);
case ItemType.Weapon: return new Weapon(userItem);
// etc
default:
throw new NotSupportedException($"Item type {itemType} is not supported");
}
}
Then use this method to create items and use them. E.g. your current code will look like:
var item = CreateItem(userItem);
item.UseItem(sender); // you don't care about specific type of item
Note: EF can use discriminator column to create entities of appropriate type automatically.
Just register building actions one time:
var builder = new ItemBuilder()
.RegisterBuilder(ItemType.Food, () => new Food())
.RegisterBuilder(ItemType.Weapon, () => new Weapon());
and use it later like this:
var item1 = builder.Build(ItemType.Food);
item1.UseItem(sender)
and here a builder code:
public class ItemBuilder
{
public ItemBase Build(ItemType itemType)
{
Func<ItemBase> buildAction;
if (itemBuilders.TryGetValue(itemType, out buildAction))
{
return buildAction();
}
return null;
}
public ItemBuilder RegisterBuilder(ItemType itemType, Func<ItemBase> buildAction)
{
itemBuilders.Add(itemType, buildAction);
return this;
}
private Dictionary<ItemType, Func<ItemBase>> itemBuilders = new Dictionary<ItemType, Func<ItemBase>> ();
}
Another option use a DI container like unity or somth:
UnityContainer.RegisterType<IItemBase, Food>("ItemType.Food");
UnityContainer.RegisterType<IItemBase, Weapon>("ItemType.Weapon");
and resolve
var item1 = UnityContainer.Resolve<IItemBase>(ItemType.Food.ToString());
public class Address
{...}
public class Object1
{
public Address Address {get;set;}
}
public class Object2
{
public Address Address {get;set;}
}
public UpdateAddress(Address address)
{
address = new Address();
}
//calling
var obj1 = new Object1();
UpdateAddress(obj1.Address);
//obj1.Address IS NULL
I cannot have my 2 classes inherit from a baseclass that has Address property (long story)
I was under the impression that when passing objects into methods they are by reference and my obj1.Address will have a new one and not be null if i am passing that property into a method.
If my assumption is wrong and it seems to be about object not being passed by reference in this instance.
How can i have a generic method that I can update a property that is the same across all my objects (I know I can return a new address object but I prefer to be passed in instead of returning)
Can this also be done by passing T<>?
UPDATE - Actual Code
Calling the methods
bool isVendorIdFromModel = UpdateVendor(entity.ExpenseVendor, entity.ExpenseVendorId, model, isNew, context);
if (isVendorIdFromModel)
{
entity.ExpenseVendorId = model.VendorId;
}
private static bool UpdateVendor(ExpenseVendor vendor, int? entityVendorId, ExpenseBaseModel model, bool isNew, ELMSContext context)
{
if (model.VendorId.HasValue)
{
if (entityVendorId != model.VendorId)
{
return true;
}
UpdateVendorInfo(model, vendor);
}
else
{
if (isNew && !string.IsNullOrEmpty(model.VendorName))
{
vendor = new ExpenseVendor
{
...
};
context.ExpenseVendors.Add(vendor);
}
if (vendor != null)
{
UpdateVendorInfo(model, vendor);
}
}
return false;
}
private static void UpdateVendorInfo(ExpenseBaseModel model, ExpenseVendor vendor)
{
vendor.Name = model.VendorName;
vendor.Address1 = model.Address1;
vendor.Address2 = model.Address2;
vendor.City = model.City;
vendor.PostalCode = model.PostalCode?.Replace(" ", string.Empty);
vendor.ProvinceId = model.ProvinceId;
}
Usual options:
shared base class (if you can change code and class hierarchy)
shared interface (if you can can change code, but no class hierarchy)
pass lambdas for getter/setter
use reflection and set by name
Since it sounds like you can't change the source lambda option may be the easiest. Following is option to "set" (when you replace whole object):
public void UpdateAddress(Action<Address> addressSetter)
{
addressSetter(new Address());
}
//calling
var obj1 = new Object1();
UpdateAddress(address => obj1.Address = address);
If you need to set properties of such object instead of replacing - pass get delegate:
public void UpdateAddress(Func<Address> addressGetter)
{
addressGetter().Street = "Dark alley";
}
UpdateAddress(address => obj1.Address);
Or use both. You can even combine them into helper class so it look close to properties (check out adapter pattern.
Note: generics not going to help you unless you can add common interface (but in that case you probably don't need generics at all).
If UpdateAddress only returns an address then change it to:
public Address UpdateAddress()
{
// set up address
return address;
}
var obj1 = new Object1();
obj1.Address = UpdateAddress();
Passing by reference and manipulating the contents of a parameter is a code smell. Write methods that return values and set the property that way.
I have a simple class that is intended for options of an winforms application. There should be a method that reset options to their default values. I know I can add a separate method to take care of this, but the code will be huge (If I add more options to the class) :
public SensorOptions()
{
ShowLabelMax = ShowLabelMin = ShowLabelAvr = ShowReceivedTextBox = true;
ChartMaxValue = 140;
ChartMinValue = -40;
ShowChartMinValue = ShowChartMaxValue = ShowChartAvrValue = ShowChartAvrLine = true;
LogFolder = Environment.SpecialFolder.MyDocuments.ToString();
LoggingEnabled = true;
}
public void ResetOptions()
{
this = new SensorOptions(); //can not do. 'this' is read-only
}
I mean I can copy/paste the code from constructor into ResetOptions() method. But is there any smarter ways to achieve this?
You cannot assign this because you may have references to this instance of your class in your program. If you could re-construct the object by re-assigning this, it would mean that all references to the old instance of the class become invalid.
No matter how many options you have in your class, you initialize each of them one or the other way (because you mention default value in your question - so you need to assign that default value somewhere at least once, probably in the constructor). Therefore, the solution to your problem is simple - move all initializers to the separate method and call it in the constructor, and then also call it every time you need to reset your options to their default values.
If any of your options are not assigned a default value explicitly, and use system default and you don't want to write option=default(optionType) for each option, you can use reflection to enumerate all fields/properties in that class and assign default values to them, like this:
public static object GetDefault(Type type)
{
if(type.IsValueType) return Activator.CreateInstance(type);
return null;
}
foreach(var field in this.GetType().GetFields())
field.SetValue(this, GetDefault(field.FieldType));
foreach(var prop in this.GetType().GetProperties())
prop.SetValue(this, GetDefault(prop.PropertyType));
Move all of the code from the constructor into the ResetOptions method, then in your constructor call the ResetOptions method. Your initialisiation code is only in one place then.
You have very simple architecture for your situation. In my opinion it would be better to apply a trick for this:
you have class for holding all your options (pseudo code):
class AllOptionsBackstage
{
public bool ShowLabelMax { get; set; }
public bool ShowLabelMin { get; set; }
public bool ShowLabelAvr { get; set; }
public AllOptionsBackstage()
{
// apply default values here
}
}
.....
class MyOptions
{
private AllOptionsBackstage _options;
public MyOptions()
{
Reset();
}
public bool ShowLabelMax
{
get{ return _options.ShowLabelMax; }
set{ _options.ShowLabelMax = value; }
}
public bool ShowLabelMin
{
get{return _options.ShowLabelMin;}
set{_options.ShowLabelMin=value; }
}
public bool ShowLabelAvr
{
get{ return _options.ShowLabelAvr;}
set{ _options.ShowLabelAvr = value; }
}
public void Reset()
{
_options = new AllOptionsBackstage(); // will reset all your options to default
}
}