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.
Related
I would have to create a constructor with great amount of parameters like:
new MyClass(param1, param2, param3, ..., param100);
Is there any way to initialize object like that in a gradual manner, like:
MyClass obj = new MyClass();
obj.Prop1 = val1;
obj.Prop2 = val2;
obj.checkIfInit() //I am not sure how to do that.
How to verify that it is initialized properly if the crazy constructor is not used?
It seems there is a high amount of repetition in your constructor, which is almost always an indicator of bad design. If possible, why not use a collection type, like an array:
new MyClass(paramArray);
Nice and clean.
If you really need that much parameters, you can usually group them together in categories. Make classes for each of them and pass those instances in. It will make use later on much easier too.
As others have pointed out, you should really not have a constructor with so many parameters - although with Dependency Injection for a data model type class, you do often end up with a lot of parameters. In that case, it's usually best to group the parameters into subsets encapsulated into their own classes.
Notwithstanding that advice, you can address the issue with a variant of the "Builder Pattern".
For example, given:
public sealed class MyClass
{
public MyClass(int prop1, string prop2, DateTime prop3)
{
Prop1 = prop1;
Prop2 = prop2;
Prop3 = prop3;
}
public int Prop1 { get; }
public string Prop2 { get; }
public DateTime Prop3 { get; }
}
First note that it has no default constructor and the properties are all read-only, making this class immutable (often a good idea).
(I have omitted parameter checking for brevity.)
Now you can write a helper class to build the object:
public sealed class MyClassBuilder
{
public MyClass Build()
{
if (!_prop1Set || !_prop2Set || !_prop3Set)
throw new InvalidOperationException("Not all properties set.");
return new MyClass(_prop1, _prop2, _prop3);
}
public MyClassBuilder Prop1(int value)
{
_prop1 = value;
_prop1Set = true;
return this;
}
public MyClassBuilder Prop2(string value)
{
_prop2 = value;
_prop2Set = true;
return this;
}
public MyClassBuilder Prop3(DateTime value)
{
_prop3 = value;
_prop3Set = true;
return this;
}
int _prop1;
string _prop2;
DateTime _prop3;
bool _prop1Set;
bool _prop2Set;
bool _prop3Set;
}
Each method for setting a property returns this, to enable fluent use like so:
var builder = new MyClassBuilder();
builder
.Prop1(1)
.Prop2("test")
.Prop3(DateTime.Now);
var myClass = builder.Build(); // Throws if not all properties set.
This gives you a great deal of flexibility for parameter validation and allowing some parameters to be omitted (by providing suitable defaults).
A real-world example of a builder class is Autofac's ContainerBuilder class, usage of which is described here.
Make all paramter to a class or struct , to help you make controctor be clean.
public class InitData
{
Parmter ....
}
new MyClass(InitData data);
Or use paramters
public class MyClass
{
public MyClass(params[] paramters)
{
foreach(p in paramters)
{ ... }
}
}
Possbie do not make a 'crazy controcter' is best soultion I think.
You can override Equals in order to check the default value:
public class MyClass {
public static readonly MyClass DefaultInstance = new MyClass();
public int Val1 { get; set; }
public int Val2 { get; set; }
// Etc...
public MyClass() {
this.Val1 = 10;
}
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
// Suitable nullity checks etc, of course :)
hash = hash * 23 + Val1.GetHashCode();
hash = hash * 23 + Val2.GetHashCode();
return hash;
}
}
public override bool Equals(Object obj) {
if (obj == this)
{
return true;
}
var other = obj as MyClass;
return other?.Val1 == this.Val1 &&
other?.Val2 == this.Val2;
// Etc...
}
}
Then you can just check using:
if (MyClass.DefaultInstance.Equals(instanceToCheck)) {
... // All defaults
}
C# compiler implicitly gives you a default constructor if you are not writing any Constructor for a class.
Now, If you are explicitly giving an Constructor now the C# Compiler will not provide you any Constructor.
i.e you have only One Constructor with you =>MyClass(param1, param2, param3, ..., param100);
Now, You are trying to Create the object without any Parameters.=>MyClass obj = new MyClass();
So, there will be error every time you compile as the Compiler does not find this type of empty overload of the Constructor which one is not taking any value.
To avoid this use an empty constructor explicitly.
Look for the Following example.
Class1 cs = new Class1();
cs.x = "xyz";
cs.y = "zyx";
if(cs!=null)
{
//This checks the Object is created or not i.e Reference is created.
Console.Write("I'm intialized");
}
else
{
Console.WriteLine("I'm not initialized");
}
And the Class for Class1 follows
class Class1
{
public string x;
public string y;
public Class1(string x,string y)
{
this.x = x;
this.y = y;
}
public Class1()
{
}
}
Check it.
I really need to have something like this:
interface IReadableVar
{
object Value { get; }
}
interface IWritableVar
{
object Value { set; }
}
interface IReadableWritableVar : IReadableVar, IWritableVar
{
}
However when I try to use IReadableWritableVar.Value I get compile errors unless I explicitly cast to base interface, like here:
static void Main()
{
IReadableWritableVar var = null;
var t = var.Value; // <-- CS0229: Ambiguity between 'IReadableVar.Value' and 'IWritableVar.Value'
var.Value = null; // <-- CS0229: Ambiguity between 'IReadableVar.Value' and 'IWritableVar.Value'
var v = ((IReadableVar)var).Value; // compiles fine
((IWritableVar)var).Value = null; // compiles fine
}
Why do I get these errors although everything should be clear to the compiler? Is there any way to fix this problem other than casting (hundreds of places in the application)?
Update: it was suggested this is a dupe of Implementing 2 Interfaces with 'Same Name' Properties but this is slightly different as in the other case there's no inheritance in interfaces. Anyway, the problem is solved now - see accepted answer.
A possible workaround can be modify your interface IReadableWritableVar like this:
interface IReadableWritableVar : IReadableVar, IWritableVar
{
new object Value { get; set; }
}
But keep in my that a valid implementation should be:
class ReadableWritableVar : IReadableWritableVar
{
public object Value
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
object IWritableVar.Value
{
set { throw new NotImplementedException(); }
}
object IReadableVar.Value
{
get { throw new NotImplementedException(); }
}
}
A more concrete example:
class ReadableWritableVar : IReadableWritableVar
{
public object Value
{
get { return ((IReadableVar)this).Value; }
set { ((IWritableVar)this).Value = value; }
}
object _val;
object IWritableVar.Value { set { _val = value; } }
object IReadableVar.Value => _val;
}
Or even better:
class ReadableWritableVar : IReadableWritableVar
{
public object Value { get; set; }
object IWritableVar.Value { set { Value = value; } }
object IReadableVar.Value => Value;
}
Interesting question. I think extension methods will help in this case.
public static class Extension
{
public static object GetValue(this IReadableVar v)
{
return v.Value;
}
public static void SetValue(this IWritableVar v, object value)
{
v.Value = value;
}
}
You need to change the code to use it:
IReadableWritableVar variable = null;
var t = variable.GetValue();
variable.SetValue(null);
The extension method does the cast for you.
Well, effectively Getter and Setter are just two methods. When we use IReadableWritableVar interface there are two methods with identical name inherited from base interfaces and compiler doesn't know which of these two should it use hence the ambiguity.
When we cast that to one of these interfaces the other member's gone and there's no error.
If we implement those member there will be no error as compiler will use that implementation:
class ReadableWritableVar : IReadableWritableVar
{
public object Value { get; set; }
}
var #var = new ReadableWritableVar();
var t = #var.Value;
Also you can use an explicit interface members implementation from #Alessandro D'Andria's answer if it is required that you use interface and not class.
using abstract class istead of interface will resolve your problem.
public abstract class ReadableWritableVar : IReadableVar, IWritableVar
{
public object Value { get; set; }
}
One possible alternative is to use explicit (java style) get and set methods instead of a property:
interface IReadableVar
{
object GetValue();
}
interface IWritableVar
{
void SetValue(object value);
}
interface IReadableWritableVar : IReadableVar, IWritableVar
{
}
The usage then becomes:
static void Main(string[] args)
{
IReadableWritableVar aVar = null;
var t = aVar.GetValue();
aVar.SetValue(null);
}
I need to create a method of class that delete the instance.
public class Car
{
private string m_Color;
public string Color
{
get { return m_Color; }
set { m_Color = value; }
}
public Car()
{
}
public void Delete()
{
/*This method will delete the instance,
so any references to this instance will be now null*/
}
}
class Program
{
static void Main( string[] args )
{
Car car = new Car();
car.Delete();
if(car==null)
Console.WriteLine("It works.");
else
Console.WriteLine("It doesn't work.")
}
}
I want to know if there is any possible solution (even if it is not recommended) how to do this.
Instance of this class will be stored in hundreds of different class. I will try to describe this, for example there will be these classes:
public class CarKey
{
private Car m_Car;
public Car Car
{
get { return m_Car; }
}
public bool CarExist{ get{ return m_Car != null; } }
public CarKey( Car car )
{
m_Car = car;
}
}
public class Garages
{
private List<Car> m_Collection = new List<Car>();
private int m_Size;
public int Size{ get{ return m_Size; } }
public Garages( int size )
{
for(int i=0;i<size;i++)
m_Collection.Add(null);
}
public bool IsEmpty( int garage )
{
return m_Collection[garage] == null;
}
public void InsertCar( Car car, int garage )
{
if( m_Collection[garage] != null )
throw new Exception("This garage is full.");
m_Collection[garage] = car;
}
public Car GetCar( int garage )
{
if( m_Collection[garage] == null )
throw new Exception("There is no car, maybe it was deleted.");
return m_Collection[garage];
}
}
From any class you can't set its value to null. This is not allowed and doesn't make sense also -
public void Delete()
{
this = null; <-- NOT ALLOWED
}
You need an instance of class to call Delete() method so why not set that instance to null itself once you are done with it.
Car car = new Car();
// Use car objects and once done set back to null
car = null;
Anyhow what you are trying to achieve is not possible in C#. I suspect
from your question that you want this because there are memory leaks
present in your current design which doesn't let the Car instance to
go away. I would suggest you better profile your application and
identify the areas which is stopping GC to collect car instance and
work on improving that area.
I would suggest , to use .Net's IDisposable interface if your are thinking of to release instance after its usage.
See a sample implementation below.
public class Car : IDisposable
{
public void Dispose()
{
Dispose(true);
// any other managed resource cleanups you can do here
Gc.SuppressFinalize(this);
}
~Car() // finalizer
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
if (_stream != null) _stream.Dispose(); // say you have to dispose a stream
}
_stream = null;
_disposed = true;
}
}
}
Now in your code:
void main()
{
using(var car = new Car())
{
// do something with car
} // here dispose will automtically get called.
}
It sounds like you need to create a wrapper around an instance you can invalidate:
public class Ref<T> where T : class
{
private T instance;
public Ref(T instance)
{
this.instance = instance;
}
public static implicit operator Ref<T>(T inner)
{
return new Ref<T>(inner);
}
public void Delete()
{
this.instance = null;
}
public T Instance
{
get { return this.instance; }
}
}
and you can use it like:
Ref<Car> carRef = new Car();
carRef.Delete();
var car = carRef.Instance; //car is null
Be aware however that if any code saves the inner value in a variable, this will not be invalidated by calling Delete.
What you're asking is not possible. There is no mechanism in .Net that would set all references to some object to null.
And I think that the fact that you're trying to do this indicates some sort of design problem. You should probably think about the underlying problem and solve it in another way (the other answers here suggest some options).
You can proxyfy references to your object with, for example, dictionary singleton. You may store not object, but its ID or hash and access it trought the dictionary. Then when you need to remove the object you set value for its key to null.
You cannot delete an managed object in C# . That's why is called MANAGED language. So you don't have to troble yourself with delete (just like in c++).
It is true that you can set it's instance to null. But that is not going to help you that much because you have no control of your GC (Garbage collector) to delete some objects apart from Collect. And this is not what you want because this will delete all your collection from a generation.
So how is it done then ? So : GC searches periodically objects that are not used anymore and it deletes the object with an internal mechanism that should not concern you.
When you set an instance to null you just notify that your object has no referene anymore ant that could help CG to collect it faster !!!
Use a collection that is a static property of your Car class.
Every time you create a new instance of a Car, store the reference in this collection.
To destroy all Cars, just set all items to null.
FLCL's idea is very correct, I show you in a code:
public class O1<T> where T: class
{
public Guid Id { get; }
public O1(Guid id)
{
Id = id;
}
public bool IsNull => !GlobalHolder.Holder.ContainsKey(Id);
public T Val => GlobalHolder.Holder.ContainsKey(Id) ? (T)GlobalHolder.Holder[Id] : null;
}
public class GlobalHolder
{
public static readonly Dictionary<Guid, object> Holder = new Dictionary<Guid, object>();
public static O1<T> Instantiate<T>() where T: class, new()
{
var a = new T();
var nguid = Guid.NewGuid();
var b = new O1<T>(nguid);
Holder[nguid] = a;
return b;
}
public static void Destroy<T>(O1<T> obj) where T: class
{
Holder.Remove(obj.Id);
}
}
public class Animal
{
}
public class AnimalTest
{
public static void Test()
{
var tom = GlobalHolder.Instantiate<Animal>();
var duplicateTomReference = tom;
GlobalHolder.Destroy(tom);
Console.WriteLine($"{duplicateTomReference.IsNull}");
// prints true
}
}
Note: In this code sample, my naming convention comes from Unity.
You can use extension methods to achive this.
public static ObjRemoverExtension {
public static void DeleteObj<T>(this T obj) where T: new()
{
obj = null;
}
}
And then you just import it in a desired source file and use on any object. GC will collect it. Like this:Car.DeleteObj()
EDIT
Sorry didn't notice the method of class/all references part, but i'll leave it anyway.
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;
}
I'm trying to make a design for some sort of IExecutable interface. I will not get into details, but the point is that I have several Actions that need to be executed from a base class. They may take different parameters (no big deal), and they may/may not return a value.
So far, this is my design:
public abstract class ActionBase
{
// ... snip ...
}
public abstract class ActionWithResultBase<T>: ActionBase
{
public abstract T Execute();
}
public abstract class ActionWithoutResultBase: ActionBase
{
public abstract void Execute();
}
So far, each of my concrete actions need to be a child from either ActionWithResultBase or ActionWithoutResult base, but I really don't like that. If I could move the definition of Execute to ActionBase, considering that the concrete class may or may not return a value, I will have achieved my goal.
Someone told me this could be done with using Func and Action, for which I totally agree, but I can't find a way to have that into one single class so that the caller would know if the action is going to return a value or not.
Brief: I want to do something like:
// Action1.Execute() returns something.
var a = new Action1();
var result = a.Execute();
// Action2.Execute() returns nothing.
var b = new Action2();
b.Execute();
If you want a lightweight solution, then the easiest option would be to write two concrete classes. One will contain a property of type Action and the other a property of type Func<T>:
public class ActionWithResult<T> : ActionBase {
public Func<T> Action { get; set; }
}
public class ActionWithoutResult : ActionBase {
public Action Action { get; set; }
}
Then you can construct the two types like this:
var a1 = new ActionWithResult<int> {
CanExecute = true,
Action = () => {
Console.WriteLine("hello!");
return 10;
}
}
If you don't want to make Action property read/write, then you could pass the action delegate as an argument to the constructor and make the property readonly.
The fact that C# needs two different delegates to represent functions and actions is quite annoying. One workaround that people use is to define a type Unit that represents "no return value" and use it instead of void. Then your type would be just Func<T> and you could use Func<Unit> instead of Action. The Unit type could look like this:
public class Unit {
public static Unit Value { get { return null; } }
}
To create a Func<Unit> value, you'll write:
Func<Unit> f = () => { /* ... */ return Unit.Value; }
The following interfaces should do the trick -- it's essentially copying the Nullable pattern
public interface IActionBase
{
bool HasResult { get; }
void Execute() { }
object Result { get; }
}
public interface IActionBase<T> : IActionBase
{
new T Result { get; }
}
public sealed class ActionWithReturnValue<T> : IActionBase<T>
{
public ActionWithReturnValue(Func<T> action) { _action = action; }
private Func<T> _action;
public bool HasResult { get; private set; }
object IActionBase.Result { get { return this.Result; } }
public T Result { get; private set; }
public void Execute()
{
HasResult = false;
Result = default(T);
try
{
Result = _action();
HasResult = true;
}
catch
{
HasResult = false;
Result = default(T);
}
}
}
public sealed class ActionWithoutReturnValue : IActionBase
{
public bool HasResult { get { return false; } }
object IActionBase.Result { get { return null; } }
public void Execute() { //... }
}
You know that you can ignore the return value of a method right? You don't have to use it.
what about something simple:
public class ActionExecuter
{
private MulticastDelegate del;
public ActionExecuter(MulticastDelegate del)
{
this.del = del;
}
public object Execute(params object[] p)
{
return del.DynamicInvoke(p);
}
}