I want to have a string, which I then want to pass to 2 variables.
One is Int, the other is string.
So normally I could do:
string1 = string2;
int1 = Convert.ToInt32(string2);
But I wonder if it's possible to do it in another approach,
I want to convert the string to Int just as it reaches the int1 variable; O don't want to convert the actually string2 to Int.
So basically like the topic says:
string1 = int1(convert to int) = string2
I am not sure if this is possible at all, hopefully it is.
Magic.
MagicInt x = 123;
string s = x;
int i = x;
Console.WriteLine("s is " + s);
Console.WriteLine("i is " + i);
public struct MagicInt
{
public MagicInt(int value)
{
_value = value;
}
public MagicInt(string value)
{
_value = int.Parse(value);
}
int _value;
public static implicit operator int(MagicInt value)
{
return value._value;
}
public static implicit operator string(MagicInt value)
{
return value._value.ToString();
}
public static implicit operator MagicInt(int value)
{
return new MagicInt(value);
}
public static implicit operator MagicInt(string value)
{
return new MagicInt(value);
}
}
Related
I am planning to create my own string class, but it will have a max length provided.
Let's call it "lString".
I want to use "lString" just like a "string" class in my code. But I will be able to set a maxlength for it.
For example, this code should be built:
// 1- No maxlength provided, so the object will be created.
lString mylString1 = "0123456789";
// 2- maxlength provided, so it will be checked, and then created.
lString mylString2 = new lString("0123456789", 10);
// 3- This time only maxlength provided, so it will be a string object with maxLength.
lString mylString3 = new lString(20);
// At the end, I should be able to use it like a regular strings:
mylString3 = mylString1 + mylString2;
// Below should throw exception at RunTime, because it will be over 20)
mylString3 = mylString1 + mylString2 + mylString1 + mylString2;
Its fairly trivial to implement a basic string class which has implicit operators to and from a normal string:
public class LimitedString
{
private readonly string value;
private readonly long maxLength;
public LimitedString(string value, long maxLength = long.MaxValue)
{
if(value != null && value.Length > maxLength)
throw new InvalidOperationException("Value is longer than max length");
this.value = value;
this.maxLength = maxLength;
}
public override string ToString()
{
return value;
}
public override int GetHashCode()
{
return value.GetHashCode();
}
public override bool Equals(object o)
{
if(o is LimitedString)
return value == ((LimitedString)o).value;
return false;
}
public static implicit operator LimitedString(string str)
{
return new LimitedString(str);
}
public static implicit operator String(LimitedString ls)
{
return ls.value;
}
}
And then your first 2 cases work as expected:
LimitedString myString1 = "0123456789";
LimitedString myString2 = new LimitedString("0123456789", 10);
However, the only way you can make your third example work is like this:
LimitedString myString3 = new LimitedString(myString1 + myString2 + myString1 + myString2, 20); // Throws exception
As once you re-assign the value your specification of the max length is lost, so you cant do this:
LimitedString myString3 = new LimitedString(20); // This is fine - you could have a constructor that just takes the max length.
myString3 = myString1 + myString2 + myString1 + myString2; // but here you're re-assigning.
Live example: https://rextester.com/KVBBQT19360
Updated: How could I make a method with two paramerters to take any primitive number type, like int, uint, float, double, etc, (except bool)?
I'm currently using an object, but that means the method can accept any type.
public int[] MyNumberMethod(object a, object b)
{
if (a is int || a is uint || a is short || a is ushort || a is long || a is ulong || a is byte || a is sbyte || a is float || a is double || a is decimal)
{
if (b is int || b is uint || b is short || b is ushort || b is long || b is ulong || b is byte || b is sbyte || b is float || b is double || b is decimal)
return new int[] { Convert.ToInt32(b), Convert.ToInt32(a) };
}
return new int[] { 0, 0 };
}
This might not be as good as the other answers, but another option is to create your own structure where you only allow a value of certain data types:
public struct Number
{
#region Static methods and fields
private static readonly Type[] allowedTypes = new Type[] {
typeof(int), typeof(uint), typeof(short), typeof(ushort),
typeof(long), typeof(ulong), typeof(byte), typeof(sbyte),
typeof(float), typeof(double), typeof(decimal)
};
private static void CheckIsNumber(dynamic val) {
if (Array.IndexOf(allowedTypes, val.GetType()) == -1) { throw new InvalidCastException("Input type must be a number."); }
}
#endregion
#region Constructor
public Number(dynamic Value) {
Number.CheckIsNumber(Value);
_value = Value;
}
#endregion
#region Properties
private dynamic _value;
public dynamic Value {
get { return _value; }
set {
Number.CheckIsNumber(value);
_value = value;
}
}
#endregion
#region Overridden methods
public override bool Equals(object obj) { return _value.Equals(obj); }
public override int GetHashCode() { return _value.GetHashCode(); }
public override string ToString() { return _value.ToString(); }
#endregion
#region Conversion operators - Number
public static implicit operator Number(uint val) { return new Number(val); }
public static implicit operator Number(short val) { return new Number(val); }
public static implicit operator Number(ushort val) { return new Number(val); }
public static implicit operator Number(long val) { return new Number(val); }
public static implicit operator Number(ulong val) { return new Number(val); }
public static implicit operator Number(byte val) { return new Number(val); }
public static implicit operator Number(float val) { return new Number(val); }
public static implicit operator Number(double val) { return new Number(val); }
public static implicit operator Number(decimal val) { return new Number(val); }
#endregion
#region Conversion operators - Misc. data types
public static implicit operator int(Number num) { return (int)num.Value; }
public static implicit operator uint(Number num) { return (uint)num.Value; }
public static implicit operator short(Number num) { return (short)num.Value; }
public static implicit operator ushort(Number num) { return (ushort)num.Value; }
public static implicit operator long(Number num) { return (long)num.Value; }
public static implicit operator ulong(Number num) { return (ulong)num.Value; }
public static implicit operator byte(Number num) { return (byte)num.Value; }
public static implicit operator sbyte(Number num) { return (sbyte)num.Value; }
public static implicit operator float(Number num) { return (float)num.Value; }
public static implicit operator double(Number num) { return (double)num.Value; }
public static implicit operator decimal(Number num) { return (decimal)num.Value; }
#endregion
}
Every time you change the value or create a new instance of the structure it will verify if the input value's data type matches any of the items in the allowedTypes array. If not it will throw an InvalidCastException.
I have also added conversion operators which will let you use this as a normal number, thus you can use it pretty much like you would use any other numerical data type:
Number myNum = 3.5;
myNum += 10.4;
double something = myNum - 6.0;
However keep in mind that you must add a decimal point when working with double, float, etc. or else it will assume that the number is an integer:
Number myNum = 3.5;
myNum -= 2;
MessageBox.Show(myNum.ToString()); //Shows "1" as the second line converts 'myNum' into an integer.
All that said, here's how you would use it for your method:
public int[] MyNumberMethod(Number a, Number b)
{
try {
return new int[] { Convert.ToInt32(b), Convert.ToInt32(a) };
}
catch(InvalidCastException) {
return new int[] { 0, 0 };
}
}
And thanks to the conversion operators you won't need to specify a (Number) conversion. For example:
byte myByte = 133;
//Unnecessary.
MyNumberMethod((Number)17.4, (Number)myByte);
//This works just as fine.
MyNumberMethod(17.4, myByte);
Well since you want to use all primitive types except the bool, how about that?
public int MyNumberMethod<T>(T number) where T : struct
{
if (!(number is bool) && number.GetType().IsPrimitive)
return Convert.ToInt32(number);
return 0;
}
e.g.
MyNumberMethod<short>(5);
All numeric types (except double and float) are implicitly convertible to decimal and float is implicitly convertible to double. So if you make overloads like:
Method(double, double)
Method(decimal, double)
Method(decimal,decimal)
Method(double, decimal)
Your method will be callable with any two numbers but only with any two numbers.
First you must call other function like GenericNumberMethod, that will contain the calling to MyNumberMethod. You must have for each data type an implementacion of GenericNumberMethod with the corresponding parameter
public int MyNumberMethod(object number) {
return Convert.ToInt32(number);
}
public int GenericNumberMethod(int number) {
return MyNumberMethod(number);
}
public int GenericNumberMethod(decimal number) {
return MyNumberMethod(number);
}
I want to have a number (let's say i) whose range is between 0 to 26 so that when the number is 26 and it is incremented by 1 (say i++) the value returns to 0 (i.e. the value is circular).
Is there such a thing in c#? What is it called? If not then how would I implement this in code (overloaded operators are accepted).
Make a property that limits the value:
private int _value;
public int Value {
get { return _value; }
set { _value = value % 27; }
}
Now when you increase the property the setter will limit the value.
Example:
Value = 25;
Value++; // Value is now 26
Value++; // Value is now 0
Value++; // Value is now 1
You can try this:
int result = number % 27;
Use modulus operator (%)
var x = 0;
x = (x+1) % 27;
if you want it to go 0,1,2,3, ..... 24,25,26, 0, 1, 2, 3, ...
use modulus 27
I don't know of any sort of 'boundaries' or rules, you can "set" for an int in the way you want. I'd suggest creating an if statement, or two, to control it. `
if( i <= 26 & i >= 0)
{ ..do something..}
else i = 0;
Something like this should accomplish what you ask:
class CircularInt
{
public int value;
public static CircularInt operator ++(CircularInt c)
{
if (c.value >= 26)
c.value = 0;
else
c.value++;
return c;
}
}
Then use it:
CircularInt cInt = new CircularInt();
cInt++;
Console.WriteLine(cInt.value);
Another option is to define your own immutable type.
public struct Value27
{
private readonly int val;
private readonly bool isDef;
private Value27(int value)
{
while (value < 0) value += 27;
val = value % 27;
isDef = true;
}
public static Value27 Make(int value)
{ return new Value27(value); }
public bool HasValue { get { return isDef; } }
public int Value { get { return val; } }
public static Value27 operator +(Value27 curValue)
{ return Make(curValue.Value + 1); }
public static Value27 operator -(Value27 curValue)
{ return Make(curValue.Value + 26); }
public static implicit operator Value27(int bValue)
{ return Make(bValue); }
public static implicit operator int (Value27 value)
{ return value.Value; }
}
I have a class that holds a bool, int and float value (plus the selected type and a name).
using UnityEngine;
using System.Collections;
[System.Serializable]
public class AnimXVariable {
public string name = "variable";
public enum VariableType { Bool, Int, Float };
public VariableType type = VariableType.Bool;
public bool boolVal = false;
public int intVal = 0;
public float floatVal = 0f;
public AnimXVariable() {
type = VariableType.Bool;
}
public AnimXVariable(VariableType newType) {
type = newType;
}
public AnimXVariable(string newName, VariableType newType, bool val) {
name = newName;
type = newType;
boolVal = val;
}
public AnimXVariable(string newName, VariableType newType, float val) {
name = newName;
type = newType;
floatVal = val;
}
public AnimXVariable(string newName, VariableType newType, int val) {
name = newName;
type = newType;
intVal = val;
}
public AnimXVariable(bool newValue) {
if(type == VariableType.Bool) boolVal = newValue;
}
public AnimXVariable(float newValue) {
if(type == VariableType.Float) floatVal = newValue;
}
public AnimXVariable(int newValue) {
if(type == VariableType.Int) intVal = newValue;
}
public static implicit operator AnimXVariable(bool val) {
return new AnimXVariable(name, type, val); //The problem is I can't access the non-static members. If I simply return new AnimXVariable(val); it does work, but the name is gone...
}
}
I'm trying to use an implicit operator to make the following work:
AnimXVariable b = new AnimXVariable("jump", VariableType.Bool, false);
b = true;
The problem is I can't access the non-static members. If I simply do
return new AnimXVariable(val);
it does work, but the name is gone... Is there any way to get information about the object inside the implicit operator code to make this work?
The problem is I can't access the non-static members.
No, you wouldn't be able to - there's no context. You're just trying to convert a bool value to anAnimXVariable. That's all the input data there is. You talk about "the object" - there is no object.
To put it another way - with your implicit operator, you should be able to write:
AnimXVariable b = true;
What would that mean? What would the name be?
I strongly suggest that you rethink trying to use an implicit conversion operator here at all. It sounds like you probably want an instance method of something like:
public AnimXVariable WithValue(bool newValue)
{
return new AnimXVariable(name, type, newValue);
}
I want some idea to how implicitly convert nullable "?" variables to district ones.
given this example
int? x = 5;
int y = x; //this gonna fail, !!!
i need some way to override = parameter, but unfortunately the = parameter is not overloadable... any suggestions
I'm using C#
You have two options, access the value directly (if you know for sure it's not null):
int y = x.Value;
or, use the null coalescing operator:
int y = x ?? 0; // 0 if null...
It is possible to implement an implicit cast operator, but only to or from types you define. For example, doing something like this..
public class NullableExtensions
{
public static implicit operator int(int? value)
{
return value ?? default(int);
}
}
.. will return a CS0556 compile error because the cast doesn't include the user-defined type.
The closest you could do is define your own Nullable type that does contain an implicit cast operator:
public struct ImplicitNullable<T> where T: struct
{
public bool HasValue { get { return this._value.HasValue; } }
public T Value { get { return this._value.Value; } }
public ImplicitNullable(T value) : this() { this._value = value; }
public ImplicitNullable(Nullable<T> value) : this() { this._value = value; }
public static implicit operator ImplicitNullable<T>(T value) { return new ImplicitNullable<T>(value); }
public static implicit operator ImplicitNullable<T>(Nullable<T> value) { return new ImplicitNullable<T>(value); }
public static implicit operator T(ImplicitNullable<T> value) { return value._value ?? default(T); }
public static implicit operator Nullable<T>(ImplicitNullable<T> value) { return value._value; }
private Nullable<T> _value { get; set; }
// Should define other Nullable<T> members, especially
// Equals and GetHashCode to avoid boxing
}
Note that although it's possible to write this code, it will likely lead to hard to trace bugs. I would recommend using an explicit cast, or throwing an exception when the value is null.
Afterwards, you can cast to and from as expected:
static void Main()
{
int myInt = 1;
int? nullableInt = 2;
ImplicitNullable<int> implicitInt;
// Convert from int or int?
implicitInt = myInt;
implicitInt = nullableInt;
// Convert to int or int?
myInt = implicitInt;
nullableInt = implicitInt;
}
Wait, I'm so confused...
Why don't you just use GetValueOrDefault?
I'm assuming this is C#.
You need to either cast, or use .value:
int? x = 5;
int y;
if(x.HasValue)
y = x.Value;
else
throw new//... handle error or something