Chaining constructors not updating variables as expected - c#

I have created a class that looks similar to the one below. As you can see I created a few constructors that I am trying to chain using : this()
class RTTutils
{
#region Variables
private bool verbose = false;
private bool canWrite = false;
private int x;
private int y;
public RTTutils()
{
x = 5;
y = 5;
RTTCalc();
}
public RTTutils(int samples, bool verbose) : this()
{
this.verbose = verbose;
this.samples = samples;
}
public RTTutils(int samples, bool verbose, bool canWrite) : this()
{
this.verbose = verbose;
this.samples = samples;
this.canWrite = canWrite;
}
public RTTutils(int samples) : this(samples, false, false)
{
}
public RTTutils(bool verbose) : this()
{
this.verbose = verbose;
}
private void RTTCalc()
{
if (this.verbose)
Console.WriteLine("Test");
}
I am trying to initialize it using
RTTutils rttcalculator = new RTTutils(true);
or any other combination for verbose and canWrite, they still remain false though. As an example in this case we will see nothing printed in the console, even though I indicated true when initializing the class.
What am I doing wrong in this case?

You expect (wrongly) boolean class fields used in method RTTCalc to have values you set in constructors with parameters. However, the parameterless constructor executes before these assignments.
Do not call RTTCalc in parameterless constructor. Provide static factory methods instead:
class RTTutils
{
private bool verbose = false;
private bool canWrite = false;
private RTTutils()
{
sampleList.Add(100); // First sample should be 100
optionChosen.Add("E");
x = 5;
y = 5;
System.IO.File.Delete(this.path);
}
private RTTutils(bool verbose) : this()
{
this.verbose = verbose;
}
private void RTTCalc()
{
if (this.verbose)
Console.WriteLine("Test");
}
public static RTTutils Create(bool verbose)
{
RTTutils result = new RTTutils(verbose);
result.RTTCalc();
return result;
}
}

Given your code above, I rewrote it and it initializes verbose and canWrite as expected.
class Foo
{
private bool _verbose = false;
private bool _canWrite = false;
private int _samples;
private int x;
private int y;
public Foo(int samples, bool verbose, bool canWrite)
{
_verbose = verbose;
_canWrite = canWrite;
_samples = samples;
x = 5;
y = 5;
RTTCalc();
}
public Foo() : this(0, false, false) { }
public Foo(int samples) : this(samples, false, false) { }
public Foo(int samples, bool verbose) : this(samples, verbose, false) { }
private void RTTCalc()
{
Console.WriteLine($"V={_verbose}, S={_canWrite}");
Console.ReadKey();
}
}
class Program
{
static void Main(string[] args)
{
Foo test1 = new Foo(1, true, false);
Foo test2 = new Foo(1, true);
Foo test3 = new Foo();
}
}
Does this work for you? If not then you are doing something else that is not shown in your code that is affecting verbose and canWrite.

Related

Implicit cast caused StackOverflowException in Unity

I have a custom Class called BoolReference.
I am using implicit cast to assign bool values to this class without calling it's Value property.
Here is the code where second cast method causes stack overflow and can someone help me to fix this?
[System.Serializable]
public class BoolReference {
[SerializeField]
private BoolVariable Variable;
public bool Value {
get => Variable.Value;
set {
Variable.Value = value;
}
}
public static implicit operator bool(BoolReference bRef) => bRef.Value;
public static implicit operator BoolReference(bool b) => b;
}
This is usage which causes the exception
public BoolReference IsInPlay;
void Awake() {
IsInPlay = false;
}
If i write IsInPlay.Value = false, then everything is ok
Actually returning a BoolReference in the conversion operator worked for me:
using System;
public class BoolVariable {
public bool Value;
}
public class BoolReference {
private BoolVariable Variable;
public bool Value {
get => Variable.Value;
set {
Variable.Value = value;
}
}
public static implicit operator bool(BoolReference bRef) => bRef.Value;
public static implicit operator BoolReference(bool b){
BoolReference br = new BoolReference();
br.Variable = new BoolVariable();
br.Value=b;
return br;
}
}
public class Program
{
static BoolReference r;
public static void Main()
{
r = false;
Console.WriteLine(r);
r = true;
Console.WriteLine(r);
}
}
...which prints:
false
true

Can't throwaway result of a val1 && val2?

I'm trying to do something like
public class Program
{
private static readonly Random r = new Random();
public static void Main()
{
RandomBool() && RandomBool();
}
private static bool RandomBool()
{
bool b = r.Next() % 2 == 0;
Console.WriteLine("Random bool value is {0}", b);
return b;
}
}
i.e. execute RandomBool() until it's false. (You can do this in JavaScript)
I guess I have to do
public static void Main()
{
bool throwAwayValue = RandomBool() && RandomBool();
}
Or is there a better way to do the same thing?
If you want to execute RandomBool repeatedly until it's false, can't you use while loop in your main?
while (RandomBool()) {
// wait
}
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/while

C++/CLI: How to write property of the property

I have 2 ref classes in C++/CLI:
>The first class:
public ref class wBlobFilter
{
int mMin;
int mMax;
bool mIsActive;
public:
// min value
property int Min
{
int get() {return mMin;}
void set(int value) {mMin = value;}
}
// max value
property int Max
{
int get(){return mMax;}
void set(int value){mMax = value;}
}
// set to true to active
property bool IsActive
{
bool get() {return mIsActive;}
void set(bool value){mIsActive = value;}
}
};
>The second class:
public ref class wBlobParams
{
wBlobFilter mFilter;
public:
property wBlobFilter Filter
{
wBlobFilter get() {return mFilter;}
void set(wBlobFilter value) { mFilter = value; }
}
};
when I call it in C# I got an error message : "Cannot modify the return value because it is not a variable"
Params.Filter.Min = 0;
So, how can I set the value of the member variable of class wBlobFilter through class wBlobParams's property directly ? Sorry for my bad English. Thank you!!!
It's hard to know what exactly you want to happen. If it inherits then the properties from the filter will be available.
public ref class wBlobParams : public wBlobFilter
{};
void f(wBlobParams^ params) {
auto max = params->Max;
}
Or replicate the property access in wBlobParams:
public ref class wBlobParams {
public:
wBlobFilter^ mFilter;
property int Max {
int get() { return mFilter->Max; }
}
};
void f(wBlobParams^ params) {
auto max = params->Max;
}
Edit 1:
Look at this. What you were doing was fine. Just your syntax for using gc handles is wrong.
public ref class cA {
int x;
public:
cA() : x(0) {}
property int X {
int get() { return x; }
void set(int _x) { x = _x; }
}
};
public ref class cB {
cA^ a;
public:
cB() : a(gcnew cA()) {}
property cA^ A {
cA^ get() { return a; }
void set(cA^ _a) { a = _a; }
}
};
void main() {
cB^ b = gcnew cB();
b->A->X = 5;
Console::WriteLine(b->A->X);
}

Override objects return value

I'm trying to compare an object with an int value such as
if (myObject - 5 == 0)
doSomething();
my class could look something like this: (most setters/getters removed, so don't mind that all variables are private)
public class SomeClass
{
public string name;
private int minValue;
private int maxValue;
private int currValue;
public int getCurrentValue()
{
return currValue;
}
}
What I'm trying to achieve is something like this:
someClassInstance - 5;
to be equal
someClassInstance.getCurrentValue() - 5;
Can I make an override for the object to act as an int (it's own variable) opposed to just being an object?
May be operator is the case?
public class SomeClass {
...
public static int operator -(SomeClass left, int right) {
if (Object.ReferenceEquals(null, left))
throw new ArgumentNullException("left");
return left.getCurrentValue() - right;
}
}
...
SomeClass someClassInstance = new SomeClass(...);
int result = someClassInstance - 5;
Another possibility (based on implicit operator) is to convert SomeClass implicitly to int whenever required:
public class SomeClass {
...
// Whenever int is requiered, but SomeClass exists make a conversion
public static implicit operator int(SomeClass value) {
if (Object.ReferenceEquals(null, value))
throw new ArgumentNullException("value");
return value.getCurrentValue();
}
}
...
SomeClass someClassInstance = new SomeClass(...);
int result = someClassInstance - 5;
Actually you would be much better off overriding operator int, that way you can do far more calculations with less overloads:
using System;
namespace Demo
{
public class SomeClass
{
public string name;
private int minValue;
private int maxValue;
public int currValue;
public int getCurrentValue()
{
return currValue;
}
public static implicit operator int(SomeClass value)
{
if (value == null)
throw new ArgumentNullException("value");
return value.currValue;
}
}
internal class Program
{
private void run()
{
var test = new SomeClass {currValue = 5};
if (test - 5 == 0)
Console.WriteLine("It worked");
if (test + 5 == 10)
Console.WriteLine("This also worked");
}
private static void Main()
{
new Program().run();
}
}
}
You could experiment with a mixture of implicit conversions and operator overloading, but from my experience you will never make it work as seamlessly as you wish (and as you could get it to work in C++).
If I were you, I would change the getCurrentValue to a property:
public int CurrentValue
{
get {return currValue};
}
and just use someClassInstance.CurrentValue -5

member variable not an option

I have many constants I need to move around in one of my classes but I'm not allowed to use member variables. What are some options?
Here's my initial try:
private void MyConstants(out int textSize, out int paddingValue, out int borderType, ...)
{
//Set them here
}
private Method1()
{
int textSize = 0;
int paddingValue = 0;
int borderValue = 0;
....
MyConstants(out textSize, out paddingValue, out borderValue)
}
private Method2()
{
int textSize = 0;
int paddingValue = 0;
int borderValue = 0;
....
MyConstants(out textSize, out paddingValue, out borderValue)
}
//Many more methods...Just seems to repetitive.
Use Private Class or Struct.
private class Variables {
public int textSize;
public int paddingValue;
public int borderValue;
}
private Variables MyConstants{
get{ return new Variables(){textSize=1, paddingValue=2, borderValue=3};}
}
If you need to initialize in constructor try using readonly instead on const.
Edit 1:
You can create a class that holds a private Dictionary:like key and value.
put a "object LoadConstant(string)" method in it that will withdraw the data.
public static class ConstantManager {
private static Hashtable _consts = new Hashtable();
private static const keyName = "Name 1";
public static void ConstantManager()
{
_consts[keyName] = ...;
}
public static Hashtable GetConstants()
{
var _copy = new Hashtable(_consts);
return _copy;
}
}
public OtherClass{
public void Method()
{
var consts = ConstantManager.GetConstants();
var a = consts[ConstantManager.keyName];
}
}

Categories

Resources