Operator Overloading- concatenating two strings - c#

In the following code, I am getting the error that One of the parameters of a binary operator must be the containing type
Whats wrong with the code?
public class Nest
{
public string a = "Test";
public string b = "Code";
}
class OperatorOverload
{
public static void Main(string[] args)
{
Nest n = new Nest();
Console.WriteLine("Enter first string");
n.a = Console.ReadLine();
Console.WriteLine("Enter second string");
n.b = Console.ReadLine();
Console.WriteLine(n.a + n.b);
}
public static string operator + (string a, string b)
{
a = string.Concat(b);
a = string.Concat(a);
return a;
}
}

Well if if was me I'd override ToString() on Nest, to return String.Concat(a,b).
Saves a lot of bogging about , when you add a c property to it.

From MSDN
Use the operator keyword to overload a built-in operator or to provide a user-defined conversion in a class or struct declaration.
what are you doing it's wrong you should define it in class like in msdn example documentation

Related

Why are the results different in int and string cases? [duplicate]

This question already has answers here:
C# difference between == and Equals()
(20 answers)
Closed 1 year ago.
im learning c# and i cant underestand that why are the results different in the following code:
public class Thing
{
public object Data = default(object);
public string Process(object input)
{
if (Data == input)
{
return "Data and input are the same.";
}
else
{
return "Data and input are NOT the same.";
}
}
}
and inside main method:
var t1 = new Thing();
t1.Data = 42;
Console.WriteLine($"Thing with an integer: {t1.Process(42)}");
var t2 = new Thing();
t2.Data = "apple";
Console.WriteLine($"Thing with a string: {t2.Process("apple")}");
and the output is:
Thing with an integer: Data and input are NOT the same.
Thing with a string: Data and input are the same.
The root of this behaviour is boxing. This is when assigning a .net value type, like an integer, to an object reference requires the creation of an object to hold the value. Because you do this twice - firstly when assigning 42 to Data and then by passing 42 as an object parameter, they are boxed into different objects which obey reference equality.
Strings are already objects but they are a special type in .net which overrides equality - see the rules.
See discussion which contains answer by #AFract!
He basically says that if (Data == input)
has to be replaced by if (Data.Equals(input))
then the problem is solved.
Please upvote his comment!
I tried this to test input type:
using System;
public class Thing
{
public object Data = default(object);
public string Process(object input)
{
if (Data.Equals(input))
{
return "Data and input are the same.";
}
else
{
return "Data and input are NOT the same.";
}
}
public dynamic Input(object myinput)
{
return myinput;
}
}
public class Program
{
public static void Main()
{
var t1 = new Thing();
t1.Data = 42;
Console.WriteLine($"Thing with an integer: {t1.Process(42)}");
var t2 = new Thing();
t2.Data = "apple";
Console.WriteLine($"Thing with a string: {t2.Process("apple")}");
Console.WriteLine($"{t1.Input(42).GetType()}");
}
}
Output is:
Thing with an integer: Data and input are the same.
Thing with a string: Data and input are the same.
System.Int32

C# custom variables

I was experimenting with making a custom variables but got stuck.
I'm still new to C# so it's only expected for me to not know what's happening, I guess..
struct MyCustomStringVariable
{
public static implicit operator MyCustomStringVariable(string input)
{
return input;
}
}
class Program
{
static MyCustomStringVariable myCustomString = "This is a string!";
static void Main(string[] args)
{
Console.WriteLine(myCustomString);
Console.ReadLine();
}
}
The following exception is thrown
System.StackOverflowException: 'Exception of type 'System.StackOverflowException' was thrown.'
This is because the code is stuck in an infinit loop. Your implicit operator will call itself because it returns the original input string which does not throw an exception because of the defined operator.
public static implicit operator MyCustomStringVariable(string input)
{
return input; // returning string type will call this method again
}
should be
public static implicit operator MyCustomStringVariable(string input)
{
// and use input somewhere on the returned type
return new MyCustomStringVariable();
}
That said there is probably no reason for you to define a type named MyCustomStringVariable but that is hard to tell because you never share the code for this or how you intend to use it.
My final goal is to visualize the process of making a string variable in my head so that I can better understand the concept behind it.
I am not sure how your custom struct or its implicit operator fit in with this goal. Why not just use the type string?
static string myCustomString = "This is a string!";
It's because the implicit operator is called recursively. You'll need to implement your structure as so, encapsulating your string variable somehow.
struct MyCustomStringVariable
{
private string value;
public MyCustomStringVariable(string input)
{
value = input;
}
public static implicit operator MyCustomStringVariable(string input)
{
return new MyCustomStringVariable(input);
}
public string GetValue()
{
return value;
}
}
Then, calling it like
Console.WriteLine(myCustomString.GetValue());
You can refer to the documentation here.

Anyone know how I can get FCL style initialisation syntax for c# types?

Instead of writing
int i = new int();
i = 7;
One can write
int i = 7;
Is there a way I can get that style of initialisation for my own types?
MyType mt = xyz;
The closest you can come is by creating implicit conversions on your type. For example:
public class Unit
{
public static implicit operator Unit( string val )
{
return Unit.Parse( val );
}
public static Unit Parse( string unitString )
{
// parsing magic goes here
}
}
This would enable you to do something like this:
Unit width = "150px";
var width = Unit.Parse("150px"); // equivalent to previous line
Note that you cannot introduce new syntax; this would be impossible to implement:
Unit width = 150px;
since 150px does not represent a valid value type.
Note that implicit casting can get you into trouble in weird ways so don't over do it. Support implicit casting only to and from types that you're really going to need.
Alternatively, if you're using C# compiler 3.5 or up you can also use inline initialization which is more verbose but also more explicit:
Unit with = new { Value=150, UnitType=Units.Pixel };
For the specific example in your comment you could add an implicit conversion operator to the type.
Note that doing this is generally not recommended because it makes your code less readable. For example, something like String2 s2 = new String2("yo") is completely explicit about what is happening; not so with something like String2 s2 = "yo".
String2 s2 = "yo";
// ...
public sealed class String2
{
public readonly string _value;
public string Value { get { return _value; } }
public String2(string value)
{
_value = value;
}
public override string ToString()
{
return Value;
}
public static implicit operator String2(string value)
{
return new String2(value);
}
}
You can do it through implicit cast operators.
Here's an article that describes the concept:
http://www.codeproject.com/KB/cs/Csharp_implicit_operator.aspx
short answer is "no you can't". You're always going to hide a new somewhere.
In your specific case you could do some trick with implicit conversions like this:
class String2 {
private readonly string WrappedString;
public String2(string wrappedString) {
this.WrappedString = "my modified " + wrappedString ;
}
public override string ToString() {
return this.WrappedString;
}
// the "magic" is here: the string you assign to String2 gets implicitly
// converted to a String2
public static implicit operator String2(string wrappedString) {
return new String2(wrappedString);
}
}
that enables you to do:
String2 test = "test";
Console.WriteLine(test.ToString()); // writes: "my modified test" to the Console
but you get the "new" hidden in the implicit conversion anyway.
Another approach which may be more general and lands you not too far from the syntax you want is through extension methods:
static class StringExtensions {
public static String2 ToString2(this string that) {return new String2(that);}
}
with that in scope, you can do this:
var test2="anothertest".ToString2();

Is it possible to cast string into my own type?

public class Currency{
private Code {get;set;}
public Currency(string code){
this.Code = code;
}
//more methods here
}
I want to be able to make my object castable
string curr = "USD";
Currency myType = (Currency)curr;
I know that I can do it with the contructor, but I have usecase where I need to cast without initializing the object...
I also believe that ill need a function like FromString() to do it
Thanks.
Yes, just add an explicit cast operator:
public class Currency {
private readonly string code;
public string Code { get { return this.code; } }
public Currency(string code) {
this.code = code;
}
//more methods here
public static explicit operator Currency(string code) {
return new Currency(code);
}
}
Now you can say:
string curr = "USD";
Currency myType = (Currency)curr;
Add this method to your Currency class:
public static explicit operator Currency(String input)
{
return new Currency(input);
}
And call it like this:
Currency cur = (Currency)"USD";
If you create your own cast-operators for your type, you can make this possible.
check out the implicit and explicit keywords.
(in this case, I'd prefer an explicit cast).
I believe this operator does what you want (as part of your Currency class):
public static explicit operator Currency(stringvalue){
return new Currency(value);
}

Using string constants in implicit conversion

Consider the following code:
public class TextType {
public TextType(String text) {
underlyingString = text;
}
public static implicit operator String(TextType text) {
return text.underlyingString;
}
private String underlyingString;
}
TextType text = new TextType("Something");
String str = text; // This is OK.
But I want to be able do the following, if possible.
TextType textFromStringConstant = "SomeOtherText";
I can't extend the String class with the TextType implicit operator overload, but is there any way to assign a literal string to another class (which is handled by a method or something)?
String is a reference type so when they developed C# they obviously had to use some way to get a string literal to the class. I just hope it's not hardcoded into the language.
public static implicit operator TextType(String text) {
return new TextType(text);
}
Add
public static implicit operator TextType(string content) {
return new TextType(content);
}
to your class? :)

Categories