Assume I have some class that represents a container. That container holds some public properties with get and set modifiers.
What I want is to implement some mechanism that will enable access and disable access to these properties reference at runtime.
For example, when some boolean flag is true, you can access these properties. That means that:
SomeClass.Property1;
Will not generate an exception and will return the object.
However, when it is false, the above line of code will throw an exception.
It is of course possible to be done when using some boolean key, and checking it at the gateway to every property.
My question is, is it possible to implement such mechanism that will enfoce these limitations for all the properties in the class, without the need to assert these conditions within every access to these properties.
Thanks for helping.
It looks like null object pattern might helps.
Simple code that shows how it can be used in your case. Not exactly the same as you want but it doesn't need to assert conditions with every access to object's properties and methods.
Entities:
abstract class AbstractEntity
{
public abstract void DoSomething();
public abstract void DoSomethingElse();
public abstract int Property { get; set; }
}
class RealEntity : AbstractEntity
{
public override void DoSomething()
{
Console.WriteLine("Something");
}
public override void DoSomethingElse()
{
Console.WriteLine("Something else");
}
public override int Property { get; set; }
}
class NullEntity : AbstractEntity
{
public override void DoSomething()
{
// do nothing or throw exception
}
public override void DoSomethingElse()
{
// do nothing or throw exception
}
public override int Property
{
get { throw new Exception(); }
set { throw new Exception(); }
}
}
Simple example of AccessContainer:
class AccessContainer
{
private RealEntity _entity = new RealEntity();
private NullEntity _nullEntity = new NullEntity();
private bool _access = true;
public AbstractEntity Entity
{
get => _access ? (AbstractEntity) _entity : (AbstractEntity) _nullEntity;
}
public void OpenAccess()
{
_access = true;
}
public void DenyAccess()
{
_access = false;
}
}
Usage:
var container = new AccessContainer();
container.Entity.DoSomething(); // prints something
var prop = container.Entity.Property; // access to property
container.DenyAccess();
container.Entity.DoSomething(); // do nothing
container.OpenAccess();
container.Entity.DoSomething(); // prints something again
container.DenyAccess();
var prop2 = container.Entity.Property; // exception
What you are asking for doesn't natively exist, you're going to have to write some sort of wrapping functionality to test whether accessibility is granted.
public interface IAccessOwner {
bool Accessible { get; }
}
[DebuggerDisplay("Accessible: {Accessible,nq} - Value: {ToString()}")]
[DebuggerTypeProxy(typeof(RestrictedObject<>.DebuggerProxy))]
public class RestrictedObject<T> {
private readonly IAccessOwner _owner;
private T _value;
public RestrictedObject(IAccessOwner owner, T initialValue)
: this(owner) {
_value = initialValue;
}
public RestrictedObject(IAccessOwner owner) {
_owner = owner ?? throw new ArgumentNullException(nameof(owner));
}
public T Value {
get {
ThrowIfInaccessible();
return _value;
}
set {
ThrowIfInaccessible();
_value = value;
}
}
public bool Accessible => _owner.Accessible;
public override string ToString() {
if (!Accessible)
return "<Inaccessible>"; // ToString should never throw
if (_value is { } val)
return val.ToString();
return "<null>";
}
private void ThrowIfInaccessible() {
if(!Accessible)
throw new InvalidOperationException("Not accessible!");
}
// explicit operator to cast directly to value
public static explicit operator T(RestrictedObject<T> ro) {
ro.ThrowIfInaccessible();
return ro.Value;
}
private sealed class DebuggerProxy {
public bool Accessible { get; }
public T Value { get; }
public DebuggerProxy(RestrictedObject<T> ro) {
bool acc = Accessible = ro.Accessible;
if (acc)
Value = ro._value;
}
}
}
You can then use properties of this type in your class:
public class MyClass : IAccessOwner {
private readonly RestrictedObject<int> _prop1;
private readonly RestrictedObject<string> _prop2;
public MyClass(int someVal) {
_prop1 = new RestrictedObject<int>(this, someVal);
_prop2 = new RestrictedObject<string>(this);
Accessible = true;
}
public bool Accessible { get; private set; }
// you determine how you want to toggle the above property.
// Exposing it publicly defeats the purpose of all of this,
// but for demo purposes only:
public void DenyAccess() {
Accessible = false;
}
public void AllowAccess() {
Accessible = true;
}
// these properties will throw exceptions if the owner
// (this object) is not currently accessible.
public int Prop1 {
get => _prop1.Value;
set => _prop1.Value = value;
}
public string Prop2 {
get => _prop2.Value;
set => _prop2.Value = value;
}
// alternatively return the wrapper itself
// allowing you to control the accessibility
// even after returning the object
public RestrictedObject<string> AltProp2 => _prop2;
}
You would then use it like the following (obviously exceptions will halt the execution, handling has been elided):
var mc = new MyClass(3);
Console.WriteLine(mc.Prop1); // prints 3
Console.WriteLine(mc.Prop2); // prints null
var temp = mc.AltProp2; // use the wrapper directly
mc.Prop2 = "Hello";
Console.WriteLine(mc.Prop2); // prints Hello
Console.WriteLine(temp.Value); // prints Hello
Console.WriteLine((string)temp); // explicit operator, prints Hello
mc.DenyAccess();
mc.Prop1 = 33; // throws!
Console.WriteLine(mc.Prop1); // throws!
Console.WriteLine(mc.Prop2); // throws!
Console.WriteLine(temp.Value); // throws!
Console.WriteLine((string)temp); // explicit operator, throws!
Console.WriteLine(temp); // prints "<Inaccessible>"
mc.AllowAccess();
string temp3 = (string)temp; // "Hello", explicit operator works again
mc.Prop1 = 22; // as do our setters
mc.Prop2 = "Goodbye";
if (temp.Accessible) {
Console.WriteLine(temp); // "Goodbye"
}
The only thing that won't throw an exception is the override of ToString on the RestrictedObject type itself since you should never throw from ToString. Instead we just return <Inaccessible>.
We've also changed how the RestrictedObject<T> is displayed in a debugger via the DebuggerTypeProxyAttribute. If someone tries to inspect the object's properties they will see the Accessible property and only if true will the wrapped object's Value appear. Otherwise, default(T) will be displayed (null for reference types, 0 for integral types and false for bool). Furthermore, through use of the DebuggerDisplayAttribute we've customized the display of the collapsed version of our object such that it shows the Accessible property alongside our customized ToString.
Note that this still has the drawback that if someone retrieves the inner/wrapped object and accessibility has later been denied, they still have the object. There's nothing you are going to be able to do to really guard against that case. You must also realize (and accept) that anyone using reflection could alter or access the state of the object if they really wanted to.
I will also note that this violates normal C# practices, which typically dictate that properties should not throw exceptions. Microsoft's own guidelines say as much, though they use the term "Avoid" rather than "Do Not". The framework itself is guilty of violating this "rule". If you're going to violate the principle of least surprise, at the very least have the courtesy to document this behavior for consumers of your API.
Suppose I have a C# class that has multiple properties that all look like this:
private bool _var1Dirty = true;
private Double? _var1;
public Double? Var1
{
get
{
if (_var1Dirty)
{
_var1 = Method_Var1();
_var1Dirty = false;
}
return _var1;
}
}
And the only differences between each of these properties would be:
The type of return var (in this case Double?, but could just as easily be int, string, etc)
The method call - Method_Var1() (Each property would have a different one)
Is there any way I could write this as a custom class?
Something along the lines of:
public class Prop
{
public delegate T Func();
private bool _dirty = true;
private T _val;
public T Val
{
get
{
if (_dirty)
{
_val = Func;
_dirty = false;
}
return _val;
}
}
}
And then I could pass into it the:
Return type T
Method Func
(PS - I know this won't compile / is dead wrong, but I wanted to give an idea of what I'm looking for)
Any help / guidance would be really appreciated.
Thanks!!!
You're close. You can do something along the lines of this:
public class Dirty<T>
{
public Dirty(Func<T> valueFactory)
{
this.valueFactory = valueFactory;
dirty = true;
}
private Func<T> valueFactory;
private bool dirty;
private T value;
public T Value
{
get
{
if (dirty)
{
value = valueFactory();
dirty = false;
}
return value;
}
}
}
And you consume it like this:
Dirty<double?> dirtyDouble = new Dirty<double?>(() => SomethingThatReturnsADouble());
double? value = dirtyDouble.Value;
I'm not sure what the dirty checking actually does, but if you need someone more complicated than a bool you can always turn it into some Func<T> the checks for dirtiness.
Edit:
Given #mikez comment and your answer, you can save yourself the creation of the Dirty<T> class by using the built in Lazy<T>, which also guarantess thread safety:
public class F
{
private Lazy<double?> lazyDouble = new Lazy<double?>(() =>
MethodThatReturnsNullableDouble(), true);
public double? Value
{
get
{
return lazyDouble.Value;
}
}
}
I have a lot of pieces of code which has to be run one time during initialization.
I have to use a boolean flag this way because it is in an event
bool _fuse;
void PerformLayout()
{
Size size;
if (!_fuse)
{
size = _InitialContainerSize;
_fuse = true;
}
else
size = parent.Size;
// ...
}
Because it happens often, I did something to make this boolean variable to look like a fuse :
So I did this:
bool _fuse;
void PerformLayout()
{
Size size;
if (!Burnt(ref _fuse))
size = _InitialContainerSize;
else
size = parent.Size;
// ...
}
If it is initialized to false, the result of the query returns false once, make the switch to true, and successive calls return true.
public static bool Burnt(ref bool value)
{
if (!value)
{
value = true;
return false;
}
else
return true;
}
Of course, it works, but I am only moderately satisfied and I am sure there is more elegant solutions. What would be yours ?
I think the general thrust in avoiding repetition here is right (even if the repetition is very small … but still). Just encapsulate it and name it properly:
struct InitializerGuard {
private bool hasRun;
public bool HasRun() {
if (hasRun)
return true;
hasRun = true;
return false;
}
}
Usage:
InitializerGuard sizeInitializer;
void PerformLayout()
{
Size size;
if (!sizeInitializer.HasRun())
size = _InitialContainerSize;
else
size = parent.Size;
// ...
}
But if you find yourself using this pattern very often this might indicate that a refactoring is in order. Maybe just assign default values to some variables? Why aren’t they initialised, anyway?
There are many ways of achieving this. You can create a complex state machine performing your logic (fastest) but for many cases, that will be overkill. Alternatively, you can keep track of an boolean which holds the state of your instance just like you have now. You can also decide to combine both solutions into a simple state machine with methods like (moderatly fast):
public class TestClass
{
private Action performLayoutAction;
public TestClass()
{
// initial state
performLayoutAction = InitializePeformLayout;
}
public void PerformLayout()
{
performLayoutAction();
}
private void InitializePeformLayout()
{
// whatever
performLayoutAction = ContiniousPerformLayout;
}
private void ContiniousPerformLayout()
{
// whatever
}
}
You can use nullable types and the null coalescing operator to declare a Size property:
Size? _containerSize;
Size ContainerSize {
get {
return (_containerSize ?? (_containerSize = _InitialContainerSize)).Value;
}
}
You can then use it like this:
void PerformLayout() {
var size = ContainerSize;
// ...
}
If the type you want to lazy initialize is a reference type it becomes even simpler.
Another option is to use the Lazy<T> type. This can used in multi-threading scenarios where the above code can break:
Lazy<Size> _containerSize = new Lazy<Size>(() => _InitialContainerSize);
void PerformLayout() {
var size = _containerSize.Value;
// ...
}
So basically I've come across some readonly properties on this one class that the writer of the class told me I could make settable for a specific task. Problem is, they get their value through manipulation most of the time, not directly from a private variable in the class.
Example:
public decimal? AccruedInterest
{
get
{
if (this.Result != null)
{
return this.GetExchangedCurrencyValue(this.Result.AccruedInterest.GetValueOrDefault(decimal.Zero));
}
return null;
}
}
So if I want to add a setter, I don't want to worry about setting that Result object because I'm not sure if on it's way back out it's going to be drawn correctly.
Would I be able to do something like this?
private decimal? _AccruedInterest;
public decimal? AccruedInterest
{
get
{
if (this._AccruedInterest.HasValue)
{
return this._AccruedInterest.Value;
}
if (this.Result != null)
{
return this.GetExchangedCurrencyValue(this.Result.AccruedInterest.GetValueOrDefault(decimal.Zero));
}
return null;
}
set
{
this._AccruedInterest = value;
}
}
Or do any of you see issues that could arise from this (besides the fact that it's now changeable)?
Well your only problem with this is if they set the value to be null and you want your property to return null rather than evaluate the if statement.
But you might not allow them to set null, in which case you should add a check in the setter.
set
{
if (value == null)
throw new NullArgumentException("AccruedInterest");
this._AccruedInterest = value;
}
If it is valid for them to set null, you probably need another boolean flag to tell if the value has been set.
private bool _accruedInterestSet;
private decimal? _accruedInterest;
public decimal? AccruedInterest
{
get
{
if (this._accruedInterestSet)
{
return this._accruedInterest; //don't return .Value in case they set null
}
if (this.Result != null)
{
return this.GetExchangedCurrencyValue(this.Result.AccruedInterest.GetValueOrDefault(decimal.Zero)) ;
}
return null;
}
set
{
this._accruedInterestSet = true;
this._AccruedInterest = value;
}
}
I don't know how it's supposed to work, but syntactically I don't see anything wrong with your code.
Is it possible to set or override the default state for a structure?
As an example I have an
enum something{a,b,c,d,e};
and a structure that links 2 values for that enum
struct SomethingData
{
something type;
int Value;
double Multipler;
SomethingData(something enumVal, int intVal, double DblVal) {...}
}
But can I specify that the default state is
SomethingData(something.c,0,1);
Struct constructors are similar to
class constructors, except for the
following differences:
Structs cannot contain explicit
parameterless constructors. Struct
members are automatically initialized
to their default values. A struct
cannot have an initializer in the
form: base (argument-list).
http://msdn.microsoft.com/en-us/library/aa288208(v=vs.71).aspx
So, short answer, no you can't override the default constructor (every struct has a parameterless constructor and you can't hide it or override it)...
You can't. Structs always have a default constructor that sets every member to its default value (null for reference types, 0 for numeric types, false for bools, etc.) This behavior cannot be changed.
You can't override the default (parameterless) constructor for a struct. You can only add new constructors, which take parameters.
http://csharp.2000things.com/2010/10/03/108-defining-a-constructor-for-a-struct/
Creating a class object will cause all of the instance fields to come into existence before anything--even the class constructor--can access it, and allocating an array will cause all of its elements to exist before anything can access the array. Both of these actions will cause all of the memory allocated to those fields or elements to be zeroed out without regard for the data types to be stored therein.
When a class-type storage location comes into existence, it will initially hold a null reference. When a structure-type storage location comes into existence, all of its fields (and any fields of structures within it) will do so simultaneously. Unlike class object instances which can only come into existence by using a constructor, structure-type storage locations are brought into existence without using any of the structure's own code. Consequently, the structure's definition will have no say in what should happen when "instances" [i.e. struct-type storage locations] come into existence.
A struct is, fundamentally, a collection of fields bound together with duct tape. If a struct is supposed to behave like something else, it should typically make its fields private and pretend to be immutable [even though struct assignment actually mutates the destination struct by overwriting all its fields with the corresponding values from the source, and the struct definition gets no say in the matter]. If, however, a struct is supposed to encapsulate a fixed set of related but independent values (e.g. the coordinates of a point), which may independently accommodate any combination of values which are legal for their respective types, a struct should simply expose its fields publicly. Some people may whine about "mutable structs are evil", but the evils only apply when invoking self-mutating methods on a struct. Structs which expose their state as fields behave like collections of variables stuck together with duct tape. If what one needs is a collection of variables stuck together with duct tape, trying to make a struct pretend to be immutable will simply make it harder to program with.
There is a workaround to make this happen by using custom Property getters. Observe:
public struct Foostruct
{
private int? _x;
private int? _y;
public int X
{
get { return _x ?? 20; } // replace 20 with desired default value
set { _x = value; }
}
public int Y
{
get { return _y ?? 10; } // replace 10 with desired default value
set { _y = value; }
}
}
This will only work for value types (which can be wrapped with nullable) but you could potentially do something similar for reference types by wrapping them in a generic class like below:
public class Wrapper<TValue>
{
public TValue Value { get; set; }
}
public struct Foostruct
{
private Wrapper<Tick> _tick;
public Tick Tick
{
get { return _tick == null ? new Tick(20) : _tick.Value; }
set { _tick = new Wrapper<Tick> { Value = value }; }
}
}
Somewhat related: I've often wanted to use the new object initializer syntax with an immutable value type. However, given the nature of a typical immutable value type implementation, there is no way to utilize that syntax, since the properties are read-only.
I've come up with this approach; In my opinion this still satisfies the immutability of the value type, but allows the code that is responsible for instantiating the value type greater control over the initialization of the internal data.
struct ImmutableValueType
{
private int _ID;
private string _Name;
public int ID
{
get { return _ID; }
}
public string Name
{
get { return _Name; }
}
// Infuser struct defined within the ImmutableValueType struct so that it has access to private fields
public struct Infuser
{
private ImmutableValueType _Item;
// write-only properties provide the complement to the read-only properties of the immutable value type
public int ID
{
set { _Item._ID = value; }
}
public string Name
{
set { _Item._Name = value; }
}
public ImmutableValueType Produce()
{
return this._Item;
}
public void Reset(ImmutableValueType item)
{
this._Item = item;
}
public void Reset()
{
this._Item = new ImmutableValueType();
}
public static implicit operator ImmutableValueType(Infuser infuser)
{
return infuser.Produce();
}
}
}
class Program
{
static void Main(string[] args)
{
// use of object initializer syntax made possible by the Infuser type
var item = new ImmutableValueType.Infuser
{
ID = 123,
Name = "ABC",
}.Produce();
Console.WriteLine("ID={0}, Name={1}", item.ID, item.Name);
}
}
Each time you get/set property you need to set default value call InitDefaultValues() method
private string _numberDecimalSeparator;
public string NumberDecimalSeparator
{
get
{
InitDefaultValues();
return _numberDecimalSeparator;
}
set
{
InitDefaultValues();
_numberDecimalSeparator = value;
}
}
...
private void InitDefaultValues()
{
if (!_inited)
{
_inited = false;
var ci = CultureInfo.CurrentCulture;
_numberDecimalSeparator = ci.With(x => x.NumberFormat).Return(x => x.NumberDecimalSeparator, ".");
...
}
}
Kinda dumb, but works
public readonly static float default_value = 1;
public struct YourStruct{
public float yourValue{
get {
return _yourValue + default_value;
}
set {
_yourValue= value - default_value;
}
}
public float _yourValue;
}
My solution. It works as well.
public struct DisplayOptions
{
public bool isUpon;
public bool screenFade;
public static DisplayOptions Build()
{
// Return default value
return new DisplayOptions(true, true);
}
DisplayOptions(bool isUpon, bool screenFade)
{
this.isUpon = isUpon;
this.screenFade = screenFade;
}
public DisplayOptions SetUpon(bool upon)
{
this.isUpon = upon;
return this;
}
public DisplayOptions SetScreenFade(bool screenFade)
{
this.screenFade = screenFade;
return this;
}
}
Use default value
// Use default
UIMaster.Instance.StartScreen("Screen 2", DisplayOptions.Build());
// Use custome
UIMaster.Instance.StartScreen("Screen 2", DisplayOptions.Build().SetScreenFade(false));
UIMaster.Instance.StartScreen("Screen 2", DisplayOptions.Build().SetUpon(false));
this should work
public struct MyStruct
{
private string myName;
private int? myNumber;
private bool? myBoolean;
private MyRefType myType;
public string MyName
{
get { return myName ?? "Default name"; }
set { myName= value; }
}
public int MyNumber
{
get { return myNumber ?? 42; }
set { myNumber = value; }
}
public bool MyBoolean
{
get { return myBoolean ?? true; }
set { myBoolean = value; }
}
public MyRefType MyType
{
get { return myType ?? new MyRefType(); }
set { myType = value; }
}
//optional
public MyStruct(string myName = "Default name", int myNumber = 42, bool myBoolean = true)
{
this.myType = new MyRefType();
this.myName = myName;
this.myNumber = myNumber;
this.myBoolean = myBoolean;
}
}
[TestClass]
public class MyStructTest
{
[TestMethod]
public void TestMyStruct()
{
var myStruct = default(MyStruct);
Assert.AreEqual("Default name", myStruct.MyName);
Assert.AreEqual(42, myStruct.MyNumber);
Assert.AreEqual(true, myStruct.MyBoolean);
Assert.IsNotNull(myStruct.MyType);
}
}
This may work...
public struct MyStruct
{
private bool _name;
public string myName
{
get { return (_name ? myName : "Default name"); }
set { _name = true; myName = value; }
}
private bool _num;
public int myNumber
{
get { return (_num ? myNumber : 42); }
set { _num = true; myNumber = value; }
}
private bool _bool;
public bool myBoolean
{
get { return (_bool ? myBoolean : true); }
set { _bool = true; myBoolean = value; }
}
private bool _type;
public MyRefType myType
{
get { return _type ? myType : new MyRefType(); }
set { _type = true; myType = value; }
}
}
Nevermind StackOverflowException
There is a workaround
public struct MyStruct
{
public MyStruct(int h = 1, int l = 1)
{
high = h;
low = l;
}
public int high;
public int low;
}