How to make value type a ref type? - c#

I have a static double variable in a static class. When I create a specific class, I use the double variable as one of the args of the constructor. What would be the easiest way of manipulating field of the object by changing the variable in static class.
Code for clarity:
public static class Vars
{
public static double Double1 = 5.0;
}
public class ClassFoo
{
public double Field1;
public ClassFoo(double number)
{
Field1 = number;
}
}
class Program
{
static void Main(string[] args)
{
ClassFoo Foo = new ClassFoo(Vars.Double1);
Console.WriteLine(Foo.Field1 + " " + Vars.Double1); //5 5
Vars.Double1 = 0.0;
Console.WriteLine(Foo.Field1 + " " + Vars.Double1); //5 0
//Foo.Field1 need to be a reference to Vars.Double1
}
}
EDIT that goes beyond the question (no more answers needed, other solution found):
I change some values (fields) very often (at runtime, or at least i would like to change them at runtime) to look for one that is right for me. Implementing:
if(KeyDown)
variable++;
if(OtherKeyDown)
variable--;
Wasn't convenient enough. I just checked Visual Studio Debugger. It's not good (fast) enough. Have to pause, change and run code code again. Method i presented would be good if changed static variable would change field of the object.

In short: no, you can't do this... at least, not seamlessly.
As noted, this is generally considered to be A Bad Idea™. There is no reference encapsulation for value types, and no simple way to implement a seamless wrapper class to do it because you can't overload the assignment operators. You can use the techniques from the Nullable<T> type to get part-way there, but no further.
The big stumbling block is the assignment operator. For the Nullable type this is fine. Since it is non-referencing (new values are distinct), an implicit conversion operator is sufficient. For a referencing type you need to be able to overload the assignment operator to ensure that assignment changes the contained data instead of replacing the wrapper instance.
About the closest you can get to full reference is something like this:
public class Refable<T> where T : struct
{
public T Value { get; set; }
public Refable(T initial = default(T))
{
Value = initial;
}
public static implicit operator T(Refable<T> self)
{
return self.Value;
}
}
This will hold a value of the specific type, will automatically convert to that type where applicable (Refable<double> will implicitly convert to double when required for instance), but all assignments must be done by referencing the Value property.
Example usage:
Refable<double> rd1 = new Refable<double>(1.5);
Refable<double> rd2 = d1;
// get initial value
double d1 = rd1;
// set value to 2.5 via second reference
rd2.Value = 2.5;
// get current value
double d2 = rd1;
// Output should be: 1.5, 2.5
Console.WriteLine("{0}, {1}", d1, d2);

What you really want to do is have Vars be a regular class, not a static class. For all methods and classes that need to deal with the variables contained in Vars, you can pass in a reference to that Vars instance.
Here is a very simple example program that illustrates the above. Note that you could probably do a lot to improve the design of your program, but this will at least get you going in the right direction, and away from trying to bend the language to do things it can't or shouldn't do.
public class SharedVars {
public static double Foo = 0.0;
}
public class ClassFoo {
private SharedVars mySharedVars;
public ClassFoo(SharedVars sharedVars) {
// save a reference to the shared variables container class for future use
mySharedVars = sharedVars;
}
// here's an example use
public void ProcessKeyDown() {
mySharedVars.foo++;
}
}
class Program {
static void Main(string[] args) {
SharedVars sharedVars = new SharedVars();
ClassFoo foo = new ClassFoo(sharedVars);
// ... some stuff happens ...
if(KeyDown)
foo.ProcessKeyDown();
}
}

Related

Constrain a string parameter to be a constant from a specific class

This is probably an incredibly dumb question but: I have a function that takes in a string, and I want to make sure that the string is a constant from a specific class. Essentially the effect I'm looking for is what enums do:
enum MyEnum {...}
void doStuff(MyEnum constValue) {...}
Except with strings:
static class MyFakeStringEnum {
public const string Value1 = "value1";
public const string Value2 = "value2";
}
// Ideally:
void doStuff(MyFakeStringEnum constValue) {...}
// Reality:
void doStuff(string constValue) {...}
I know this can technically be achieved by doing some thing like
public static class MyFakeStringEnum {
public struct StringEnumValue {
public string Value { get; private set; }
public StringEnumValue(string v) { Value = v; }
}
public static readonly StringEnumValue Value1 = new StringEnumValue("value1");
public static readonly StringEnumValue Value2 = new StringEnumValue("value2");
}
void doStuff(MyFakeStringEnum.StringEnumValue constValue) {...}
But it feels kind of overkill to make an object for just storing one single value.
Is this something doable without the extra code layer and overhead?
Edit: While a enum can indeed be used for a string, I'd like to avoid it for several reasons:
The string values may not always be a 1:1 translation from the enum. If I have a space in there, different capitalization, a different character set/language, etc. I'd have to transform the enum in every function where I want to use it. It might not be a lot of overhead or a performance hit in any way, but it still should be avoided--especially when it means that I'm always mutating something that should be constant.
Even if I use a separate string array map to solve the above function, I would still have to access the translations instead of just being able to use the enum directly. A map would also mean having two sources for the same data.
I'm interested in this concept for different data types, ex. floats, ulongs, etc. that cannot be easily represented by enum names or stored as an enum value.
As for string -> enum, the point of using an enum in the first place for me is that I can rely on intellisense to give me a constant that exists; I don't want to wait until compile time or runtime to find out. Passing in an actual string would be duck typing and that's something I definitely don't want to do in a strongly typed language.
I would suggest you create an enum and parse the string value into an enum member.
You can use the Enum.Parse method to do that. It throws ArgumentException if the provided value is not a valid member.
using System;
class Program
{
enum MyEnum
{
FirstValue,
SecondValue,
ThirdValue,
FourthValue
}
public static void doStuff(string constValue)
{
var parsedValue = Enum.Parse(typeof(MyEnum), constValue);
Console.WriteLine($"Type: { parsedValue.GetType() }, value: { parsedValue }");
}
static void Main(string[] args)
{
doStuff("FirstValue"); // Runs
doStuff("FirstValuesss"); // Throws ArgumentException
}
}

Link Two Properties/Variables

Let me explain my situation. I have a program who reads an external connection and gives me an array of integers (or booleans). Those inputs should feed an object that has some properties (X, Y, Z, for example). So, if a read a value on array, i should write those values in the properties. Is there a way to pass those values by ref (for example) ? Thinking logically , the best way way would be pointers (property X pointing to array[0]), but these aren't very unclear to me.
I can create a way to look for changes in array (but is a very large array, +60000), then update my object. But i think this would be a bad ideia.
Sorry if i wrote any crap, i'm just starting on C#.
Some pseudo code to help.
class obj
{
int X {get; set;}
public obj(ref int x)
{
X = x;
}
}
class main
{
void main()
{
int a;
obj test = new obj(ref a);
}
}
So if: a = 10, obj.X = 10 too.
public class MyClass
{
private int[] backingArray;
public int X
{
get
{
if (backingArray == null)
return -1;
else
return backingArray[0];
}
}
public MyClass(int[] array)
{
if (array.Length > 0)
backingArray = array;
}
}
class Main
{
void Main()
{
int[] array = new int[] { 2 };
MyClass test = new MyClass(array);
array[0] = 6;
Console.WriteLine(test.X);//prints 6
}
}
Of course this only works with reference types (arrays are reference types). If you wanted to do this whole thing with a value type, you'd need to "wrap" it in some reference type. You can use a class such as the following to wrap anything if you don't have anything convenient.
public class Wrapper<T>
{
public T Value { get; set; }
}
It's not possible to use ref in the manor that you've shown in the OP. You wouldn't be able to store the value that was passed by reference. If you could, then you could end up passing some value on the stack and then having the created object that holds the reference living longer than the item on the stack. If that happened you would end up with a reference it a location in memory that no longer holds the variable you intended. This was somewhat of a gotcha in C++ that the designers of C# went out of their way to ensure can't happen (at least not without a lot of work).

Unexpected behavior with Struct internal values

*Solved. Thanks for the explanations guys, I didn't fully understand the implications of using a value type in this situation.
I have a struct that I'm using from a static class. However, the behavior is showing unexpected behavior when I print it's internal state at runtime. Here's my struct:
public struct VersionedObject
{
public VersionedObject(object o)
{
m_SelectedVer = 0;
ObjectVersions = new List<object>();
ObjectVersions.Add(o);
}
private int m_SelectedVer;
public int SelectedVersion
{
get
{
return m_SelectedVer;
}
}
public List<object> ObjectVersions;//Clarifying: This is only used to retrieve values, nothing is .Added from outside this struct in my code.
public void AddObject(object m)
{
ObjectVersions.Add(m);
m_SelectedVer = ObjectVersions.Count - 1;
}
}
Test code
VersionedObject vo = new VersionedObject(1);
vo.AddObject(2);//This is the second call to AddObject()
//Expected value of vo.SelectedVerion: 1
//Actual value of vo.SelectedVersion: 1
Now, if you test this code in isolation, i.e., copy it into your project to give it a whirl, it will return the expected result.
The problem; What I'm observing in my production code is this debug output:
objectName, ObjectVersions.Count:2, SelectedVer:0,
Why? From my understanding, and testing, this should be completely impossible under any circumstances.
My random guess is that there is some sort of immutability going on, that for some reason a new struct is being instanced via default constructor, and the ObjectVersions data is being copied over, but the m_SelectedVersion is private and cannot be copied into the new struct?
Does my use of Static classes and methods to manipulate the struct have anything to do with it?
I'm so stumped I'm just inventing wild guesses at this point.
Struct is value type. So most likely you are creating multiple copies of your object in your actual code.
Consider simply changing struct to class as content of your struct is not really good fit for value type (as it is mutable and also contains mutable reference type).
More on "struct is value type":
First check FAQ which have many good answers already.
Value types are passed by value - so if you call function to update such object it will not update original. You can treat them similar to passing integer value to function: i.e. would you expect SomeFunction(42) to be able to change value of 42?
struct MyStruct { public int V;}
void UpdateStruct(MyStruct x)
{
x.V = 42; // updates copy of passed in object, changes will not be visible outside.
}
....
var local = new MyStruct{V = 13}
UpdateStruct(local); // Hope to get local.V == 42
if (local.V == 13) {
// Expected. copy inside UpdateStruct updated,
// but this "local" is untouched.
}
Why is this a struct and not a class? Even better, why are you tracking the size of the backing store (List<T>) rather than letting the List<T> track that for you. Since that underlying backing store is public, it can be manipulated without your struct's knowledge. I suspect something in your production code is adding to the backing store without going through your struct.
If it were me, I'd set it up something like this, though I'd make it a class...but that's almost certainly a breaking change:
public struct VersionedObject
{
public VersionedObject()
{
this.ObjectVersions = new List<object>() ;
return ;
}
public VersionedObject(object o) : this()
{
ObjectVersions.Add(o);
return ;
}
public VersionedObject( params object[] o ) : this()
{
ObjectVersions.AddRange( o ) ;
return ;
}
public int SelectedVersion
{
get
{
int value = this.ObjectVersions.Count - 1 ;
return value ;
}
}
public List<object> ObjectVersions ;
public void AddObject(object m)
{
ObjectVersions.Add(m);
return ;
}
}
You'll note that this has the same semantics as your struct, but the SelectedVersion property now reflects what's actually in the backing store.

C#: Array of references / pointers to a number of integers

I would like to hold references to a number of shorts in an array. I assumed I could just create the shorts and then add them to the array. So... every time the referenced object is changed, this is reflected in the array, and vice versa. Doing some trials convinced me that it does not quite work that way. In fact, it looks like the value is transferred but not a reference.
Below code creates two shorts, adds these to an array as objects, then changes the original short. However, when accessing the assumed referenced short in the array it has not changed, which leads me to believe that it is a wholly new object that has nothing to do with the original one.
Console.WriteLine("Testing simple references:");
short v1 = 1;
short v2 = 2;
object[] vs = new object[2];
vs[0] = v1;
vs[1] = v2;
v1 = 1024;
v2 = 512;
Console.WriteLine(" v1: " + (short)vs[0]);
Console.WriteLine(" v2: " + (short)vs[1]);
I am misunderstanding something fundamental here and would appreciate if someone could explain, and perhaps point me to a solution that would do what I want.
There are two kinds of types in the C# type system "value types" and "reference types".
Value types are copied by value; when you copy one, you get a wholly new object that has nothing to do with the original.
Reference types are copied by reference; when you copy one, you are actually copying a reference to some storage location. You get two references that both refer to one object.
Shorts are value types.
If you want a short to be a reference type, then you could make a reference type wrapper:
class ReferenceType<T> where T : struct
{
public T Value { get; set }
public ReferenceType(T value) { this.Value = value; }
}
var v1 = new ReferenceType<short>(1);
var v2 = new ReferenceType<short>(2);
var vs = new ReferenceType<short>[2] { v1, v2 };
v1.Value = 1024;
v2.Value = 512;
Console.WriteLine(vs[0].Value);
Console.WriteLine(vs[1].Value);
And there you go.
Now, that will give you reference access to the short because the short is actually stored in the field associated with the value property of the class. If you then say:
v2 = new ReferenceType<short>(3);
Console.WriteLine(vs[1].Value);
you won't get "3" -- v2 now refers to a different object than vs[1]. If what you really want to capture is a reference to a variable then what you want to use is a closure.
class ReferenceToVariable<T>
{
private Func<T> getter;
private Action<T> setter;
public ReferenceToVariable(Func<T> getter, Action<T> setter)
{
this.getter = getter;
this.setter = setter;
}
public T Value { get { return getter(); } set { setter(value); } }
}
...
short v1 = 1;
short v2 = 2;
var vs = new []
{
new ReferenceToVariable<short>(()=>v1, x=>{v1=x;}),
new ReferenceToVariable<short>(()=>v2, x=>{v2=x;})
};
v1 = 123;
vs[1].Value = 456;
Console.WriteLine(vs[0].Value); // 123
Console.WriteLine(v2); // 456
Here we capture in the array objects which know how to get and set the current values of v1 and v2.
Now, if what you want to do is make an alias to another variable directly, without this object in the way, then there is only one way to do that in C#:
void M(ref short x)
{
x = 123;
}
...
short y = 1;
M(ref y);
Now "x" and "y" are two names for the same variable. However, the concept of "make an alias to another variable" only works in C# when the aliasing variable is a formal parameter of a method. There is no way to do it in general.
Now, we could in theory do something like what you want. We could support "ref locals":
UPDATE: The "theoretical" feature I discuss here was added to C# 7.0.
short v1 = 1;
ref short rv1 = ref v1;
rv1 = 123;
Console.WriteLine(v1); // 123
That is, rv1 becomes an alias for v1. C# does not support this, but the CLR does and therefore we could support it. However, the CLR does not support making arrays of "ref" element type, or fields that store refs. So in that sense, you couldn't do what you want.
C# does support some special "hidden" features for passing around objects that act like references to variables but are lighter weight than the "two delegate" reference mentioned above. However, these special features are only for bizarre interop scenarios and I recommend against them. (And again, you can't make an array that stores typed references.) I don't think I'll talk about those features more in this answer; you really don't want to go there, believe me.
Short is a value type, but you're trying to make it behave like a reference type.
You can create a class with a short property and then use an array of that class:
public class MyShort
{
public short Value {get; set;}
}
public class SomeOtherClass
{
public void SomeMethod()
{
MyShort[] array = new MyShort[2];
array[0] = new MyShort {Value = 5};
array[1] = new MyShort {Value = 2};
array[0].Value = 3;
}
}
There's potentially some work you can do there to make it smoother (like implementing a converter from short to your wrapper class and back).
The short type is a value type and does not work like reference types which behaves like you are expecting your shorts to behave. When you assign a value type to a variable, its value is assigned, not its reference. vs[0] will hold a copy of the value you assigned to v1.
If you really need to have the values in the array change when you change the original value, you need to wrap your short in a reference type. Here is an example:
public class ShortHolder {
public short Value { get; set; }
}
Then you can use it like this:
var v1 = new ShortHolder() { Value=123; }
var shortArray = new ShortHolder[1];
shortArray[0] = v1;
If you change v1.Value, then shortArray[0].Value will also change.
Value types are called value types because they are passed by value when passed to methods or assigned via the = operator.
Another (and more correct) way to look at it is that shorts, ints, etc. are immutable => they cannot be changed. So you basically cannot change a short. If you need an object of type short to change somewhere you need to create a class to hold this object like this:
public class ShortWrapper
{
public short ShortValue {get; set;}
}
class Program
{
static void Main(string[] args)
{
ShortWrapper short1 = new ShortWrapper{ ShortValue = 1};
ShortWrapper short2 = new ShortWrapper { ShortValue = 2 };
ShortWrapper[] shorts = new ShortWrapper[] { short1, short2 };
shorts[0].ShortValue = 5;
Console.WriteLine(short1.ShortValue);
}
}
Essentially the code is replacing the object of type short with a new object.
BTW chances are that there is something wrong with your design if you need to wrap a naked short. You either should be using some more complex object already or should be working with the array of shorts in some other way. But I guess you are just testing.
The fundamental problem is that short is a struct and not an object. So basically an array of short is actually an array of short and not an array of references to short objects.
To solve the problem you can "box" the short in a class (but it's going to be tedious)
Try with the following:
public class MyShort { public Value { get; set; } }
You can use ReferenceType transparently as if float, int etc. were actually reference types if you add a conversion operator to the class:
class ReferenceType<T> where T : struct
{
public T Value { get; set; }
public ReferenceType(T value) { this.Value = value; }
public static implicit operator ReferenceType<T>(T b)
{
ReferenceType<T> r = new ReferenceType<T>(b);
return r;
}
public static implicit operator T(ReferenceType<T> b)
{
return b.Value;
}
}
ReferenceType<float> f1 = new ReferenceType(100f);
f1 = 200f;
float f2 = f1;
By using the explicit qualifier instead of implicit, you can require casts for these conversions, if you want to make things clearer at the expense of a little verbosity.

Using real world units instead of types

I have a project with many calculations involving a lot of real world units :
Distance;
Temperature;
Flow rate;
...
This project involves complicated and numerous calculation formulas.
That's why I supposed the use of custom types like Temperature, Distance... can be good for code readability. For example:
Temperature x = -55.3;
Meter y = 3;
or
var x = new Temperature(-55.3);
I tried to make a Temperature class that uses a double internal value.
public class Temperature
{
double _Value = double.NaN;
public Temperature() { }
public Temperature(double v) {
_Value = v;
}
public static implicit operator Temperature(double v) {
return new Temperature(v);
}
}
But class are nullable. This mean that something like :
Temperature myTemp;
is "correct" and will be null. I dont want this. I dont want to use structs because they are too limited :
They cannot use parameterless constructor nor instance field intializers like double _Value = double.Nan; to define a default value (I wand default underlying double value to be NaN)
They cannot inherits from classes, they only can implement Interfaces
Them I wonder whether there is a way to tell C#:
Temperature myTemp = 23K; // C# does not implement anything to make K unit...
but I know C# does not handle no custom units.
Temperature myTemp = new Kelvin(23); // This might work
So I imagine I could create two Celsius and Kelvin classes that inherits from Temperature, and then I started to wonder if the idea really worth it, because it involves a lot of coding and testing.
That's the discussion I would like to start :
Would the use of real world units in my code instead of .NET types would be a good thing or not ? Did anyone this already ? What are the pitfalls and the best practices ? Or should I better keep stay away from this and use standard .NET types ?
Why not try a struct that looks like this:
/// <summary>
/// Temperature class that uses a base unit of Celsius
/// </summary>
public struct Temp
{
public static Temp FromCelsius(double value)
{
return new Temp(value);
}
public static Temp FromFahrenheit(double value)
{
return new Temp((value - 32) * 5 / 9);
}
public static Temp FromKelvin(double value)
{
return new Temp(value - 273.15);
}
public static Temp operator +(Temp left, Temp right)
{
return Temp.FromCelsius(left.Celsius + right.Celsius);
}
private double _value;
private Temp(double value)
{
_value = value;
}
public double Kelvin
{
get { return _value + 273.15; }
}
public double Celsius
{
get { return _value; }
}
public double Fahrenheit
{
get { return _value / 5 * 9 + 32; }
}
}
Then use it like, say, this:
static void Main(string[] args)
{
var c = Temp.FromCelsius(30);
var f = Temp.FromFahrenheit(20);
var k = Temp.FromKelvin(20);
var total = c + f + k;
Console.WriteLine("Total temp is {0}F", total.Fahrenheit);
}
One way to achieve this would be to use composition of the basic object (Temperature in your case) with a TemperatureTraits class that specializes the basic object. By analogy to C++, the String equivalent class basic_string is actually a class template (generic in C# terms) that has template parameters not only for the string element (char, wide char) but also a traits class that elaborates on how the class behaves for a given type of string element (e.g. char_traits).
In your case, you might define a generic like
public class MeasurableWithUnits<class M MEASURABLE, class U UNITS>
and then implementation would depend not only on the measurable class but also on the units class. How useful this would be in practice would depend on how much of such an object could be made truly generic - what operations are common across combinations of Measurable and Units?
There is a research paper on C# traits here, if this approach looks interesting.
I think it can be good when you want to add more specific functionality to a temperature (for example: IsFreezing()).
To solve the issue with Kelvin and Celsius: make an interface ITemperature and a baseclass. In the baseclass, you can implement the interface and fill in the details that are the same for all classes.
If you use a struct, then this cannot be null
struct Temperature
{
double _Value;
}
I don't think it's worth adding static types for units in C#. You would need to overload so many operators(for all unit combinations, not just for all units). And build in functions like Math.Sqrt work on normal doubles,...
What you might try is using dynamic types:
class PhysicalUnit
{
}
struct PhysicalValue
{
readonly Value;
readonly PhysicalUnit;
}
And then when compiling in debug mode add checks if the units fit together. And in release just remove the PhysicalUnit field and all the checks, and you're (almost) as fast as code using normal doubles.
I would make Temperature an abstract class that stores the temperature (in Kelvin!) in an InternalTemperature property.
A derived class Celcius would translate the input value internaly to Kelvin. It would have a (readonly) Value property that translated the internal value back.
Comparing them (is one warmer than the other) would then be easy.

Categories