C# Operator Overloading, rewriting string? - c#

I'm very fresh to C#
Currently learning Operator overloading
i'm trying to do something like this:
string val = 500; (I can't implicitly)
and then
Number n1 = val;
I manages to get the Number n1 = someintvalue, for instance:
Number n1 = 500;
like this:
public struct Number
{
public int Value { get; set; }
public Number(int Val)
{
Value = Val;
}
public static implicit operator Number(int num)
{
return new Number(num);
}
}
However, when trying to make Number n1 = val; (when val is a string)
I simply cant since the first line cant compile:
string val = 500;
and the following wont work:
public static implicit operator string(int A)
{
return new string(A);
}
because of 1 error which i can not understand
1)User-defined conversion must convert to or from the enclosing type
by the way i get the idea of op overload
underthis specific case of: return new Number(num);
I simply init the ctor
still need some more fundemental understanding
thx ahead!

I presume the function you quote is within the Number class. You have added a conversion operator from an int to a string within that class, which is not legal. You can only add operators that convert to or from the type they're defined in, such as:
public static implicit operator string(Number A)
{
return new string(A.Value);
}
which will fail because string does not have a constructor that takes an int. You could do:
public static implicit operator string(Number A)
{
return A.ToString();
}
But the standard way to "convert" to a string is to overload the ToString method, which the compiler often calls automatically when a conversion to string is requested:
public override string ToString()
{
return Value.ToString();
}

Related

Why can't I use the print function inside the class when doing operator overloading?

I didn't get any errors. I'm just wondering. Why it doesn't work when I typed "no4.Print();". did not class already create?
I was learning operator overloading. i noticed that it only works when i use Console.WriteLine func. If i tried to use Print function inside the class it errors.
using System;
class Number{
private int myNumber;
public Number(int myNumber){
this.myNumber=myNumber;
}
public static Number operator *(Number a, Number b){
return new Number(a.myNumber*b.myNumber);
}
public void Print(){
Console.WriteLine(this.myNumber);
}
public static implicit operator int(Number a) {
return a.myNumber;
}
public static implicit operator Number(int a) {
return new Number(a);
}
}
class HelloWorld {
static void Main() {
Number no1 = new Number(5);
Number no2 = new Number(2);
Number no3 = no1*no2;
no3.Print();
int no4 = new Number(1312);
Console.WriteLine(no4); //It doesnt work no4.Print();
Number no5 = 2121;
no5.Print();
}
}
You can't call no4.Print(); because the int type/class does not have such a method. Also, nobody is telling the variable to get converted to a Number object. However, when you write something like
((Number)no4).Print();
you are explicitly converting your int value to a Number object with the help of your defined implicit operator Number(int a) operator.

how can I create ToInt32 method in System namespace?

As you know, we can convert to string using Convert.ToString or ToString. I want to make the same thing for integer, byte etc. Furthermore, I want to see this method for every object when I put dot.
How should I write the method?
You are looking for a extension method. just create a static class and a static method inside it like:
public static class Exts
{
public static int ToInt32(this string x)
{
int result = 0;
int.TryParse(x, out result);
return result;
}
}
of course my method is a sample and it just returns 0 for any string value that is not castable to int, however you may write any code, accept default value as argument, throw exception,...
Then you can use it like:
string a = "123";
int b = a.ToInt32();
int c = "321".ToInt32();
Write a generic extension that converts any type to Int32:
public static class ObjectExt {
public static int ToInt<T>(this T obj) => Convert.ToInt32(obj);
}

Overloading Primitive Operator (C#)

Is there a way I can overload primitives, for example addition with doubles? I want to automatically round the doubles whenever an operation is performed. My current code is this:
class Test{
public static double operator +(double x, double y){
return Math.Round(x + y)
}
}
but there's an unfortunate error that says "One of the parameters of a binary operator must be the containing type".
No, and this would be horrible. Users using your library would suddenly get different behaviors from their double variables!
You can write and use a wrapper object however:
public struct MyDouble
{
public double Value {get; set;}
public MyDouble(double initValue)
{
Value = initValue;
}
public static double operator +(MyDouble x, MyDouble y){
return Math.Round(x.Value + y.Value)
}
}
You can also make it castable to/from a double, among other options. This way users know they are using your object and won't be surprised when their math operations are rounded.
If you want to assign from a simple double, you would need to define an implicit operator, similar to that of Nullable<T> (source):
public static implicit operator MyDouble(double value) {
return new MyDouble(value);
}
You can't overload operators on primitive types. This would cause havoc in your codebase.
What you can do instead, is to create a simple wrapper around the primitive type, let's say RoundedDouble:
public struct RoundedDouble : IEquatable<RoundedDouble>, IComparable<RoundedDouble>
{
public readonly double Value;
public RoundedDouble(double value)
{
Value = Math.Round(value); // Or anything else
}
public static implicit operator RoundedDouble(double value)
{
return new RoundedDouble(value);
}
public static implicit operator double(RoundedDouble wrapper)
{
return wrapper.Value;
}
public int GetHashCode()
{
return Value.GetHashCode();
}
public bool Equals(object other)
{
if (other is RoundedDouble)
return ((RoundedDouble)other).Value == Value;
return false;
}
public string ToString()
{
return Value.ToString();
}
// Add your operators here, and implement the interfaces
}
This is a structure. It has the same value semantics as a double.
Extend it by adding the operators, and by implementing at least IEquatable<RoundedDouble> and IComparable<RoundedDouble>.

C# Implicit/Explicit Type Conversion

I have a simple scenario that may or may not be possible. I have a class that contains an integer, for this purpose I'll make it as simple as possible:
public class Number
{
public int Value {get; set;}
public string Name {get; set;}
}
public static void Print(int print)
{
Console.WriteLine(print);
}
public static string Test()
{
Number num = new Number (9, "Nine");
Print(num); //num "overloads" by passing its integer Value to Print.
}
// Result
// 9
How do I make the Test() function work as I have coded it? Is this even possible? I think this can be done with the explicit/implicit operator but I can't figure it out.
Try something like this
public static implicit operator int(Number num)
{
return num.Value;
}
class Number
{
public static implicit operator int(Number n)
{
return n.Value;
}
}
Implicit conversion
// Implicit conversion. num long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;
Explicit Conversion
class Test
{
static void Main()
{
double x = 1234.7;
int a;
// Cast double to int.
a = (int)x;
System.Console.WriteLine(a);
}
}
Hope this may help you.
Implicit type conversion: Implicit type conversion takes place between smaller to larger integral types but not vice-versa or between derived class and base class. Conversion takes place in type safe manner by C# and no data loss takes place.
For example,
int a = 10;
long b = a;
float f = a;
Explicit type conversion: Explicit type conversion done by using built-in C# functions. Data may be lost while explicit type conversion, means if we convert double to int then precision may be lost. Explicit type conversion require casting. To do a casting, need to specify the type that you are casting to in front of the value or variable to be converted.
For example,
double d = 10.20;
int a = (int)d;
//Output: 10
To understand in details follow C# Basics - C# Type Conversion

two ways of displaying a decimal

let's say I have a list of decimals :
List<decimal> values;
and 2 function to display a decimal :
string DisplayPct(decimal pct)
{
return pct.ToString("0.00 %");
}
string DisplayValue(decimal val)
{
return val.ToString("0.00");
}
What would be the best mechanism to implement so I could know which function to call depending on the value?
I would have liked to have for instance typedefs in C#. That way, I could have declared a type Percent and a type Decimal that would both represent decimal values, but then I could know how to display the value based on its type.
Any equivalent in C# ?
Thanks
Here are my classes :
public class Percent
{
public decimal value;
public Percent(decimal d) { value = d; }
public static implicit operator Percent(decimal d) { return new Percent(d); }
public static implicit operator decimal(Percent p) { return p.value; }
}
public class DecimalPrecise
{
public decimal value;
public DecimalPrecise(decimal d) { value = d; }
public static implicit operator DecimalPrecise(decimal d) { return new DecimalPrecise(d); }
public static implicit operator decimal(DecimalPrecise d) { return d.value; }
}
Wrap percent in a class. A bit of work on your part. Just make sure to define the implicit operator to capture decimals, and some of the other operations and ToString as you require.
It sounds like you want two classes: a decimal and a percent. Each one will have a ToString that prints appropriately. If they both have the same interface, you can have a collection of both in a List using that common interface.

Categories

Resources