I have a string variable operation_sequence. I'd like to remove another string variable job.Description from it.
For example, if I wanted to add job.Description to operation_sequence, I can do:
operation_sequence += job.Description;
and this works. But if I wanted to remove job.Description from operation_sequence, the following code does not work:
operation_sequence -= job.Description;
What's the best way to remove job.Description from operation_sequence?
You could easily use String.Replace():
String HelloWord = "Hello World!";
String NewWord= HelloWord.Replace("o","");
NewWord will be=Hell Wrld!
We can't use -= or - for string. But we can implement it for our own string class.
Solution 1
public class MyString
{
public string Value { get; private set; }
public MyString(string value)
{
Value = value;
}
public static MyString operator +(MyString left, MyString right)
{
return new MyString(left.Value + right.Value);
}
public static MyString operator -(MyString left, MyString right)
{
if (string.IsNullOrEmpty(left.Value))
return left;
if (string.IsNullOrEmpty(right.Value))
return left;
if (left.Value.EndsWith(right.Value))
{
int startIndex = left.Value.Length - right.Value.Length;
string result = left.Value.Substring(0, startIndex);
return new MyString(result);
}
return left;
}
public static implicit operator string(MyString value) => value.Value;
public static implicit operator MyString(string value) => new MyString(value);
}
As you know we can't overload -= and +=(See this). Therefore I overloaded - and +. Now we can use our class like this:
MyString s1 = "This is ";
MyString s2 = "just a test";
string s3 = s1 + s2; // s3 = "This is just a test"
string s4 = s3 - s2; // s4 = "This is "
Because of public static implicit operator MyString(string value) => new MyString(value) we can have something like MyString s1 = "test". It implicitly converts string to MyString.
Because of public static implicit operator string(MyString value) => value.Value we can have something like string s3 = MyString("test"). It implicitly converts MyString to string.
In the - operator we checked if the left operand ends with the right one, we removed it.
Solution 2
And also we can simply use an extension method like this:
public static class StringExtension
{
public static string MinusString(this string baseString, string minusString)
{
if (string.IsNullOrEmpty(baseString))
return baseString;
if (string.IsNullOrEmpty(minusString))
return baseString;
if (baseString.EndsWith(minusString))
{
int startIndex = baseString.Length - minusString.Length;
string result = baseString.Substring(0, startIndex);
return new MyString(result);
}
return baseString;
}
}
and now we can use it like this:
string s = "This is just a test";
string s3 = s.MinusString("a test"); // s3 = "This is just "
s3 = s3.MinusString("just "); // s3 = "This is "
Solution suggested by Klaus Gütter worked for me, which is defining operation_sequence as a List and converting it to a string only after manipulation, using String.Join.
private string operation_sequence;
List<string> ops = new List<string>(3);
// Add item to List:
ops.Add(job.Description);
// or Remove item from List:
ops.Remove(job.Description);
//then update operation_sequence string with values from List<string>:
operation_sequence = String.Join(", ", ops);
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
The question here is
Write a program to construct a class "MyString" which has one string and length of that string as its data members. now overload '-' operator to copy the string into another string.
I'm not understanding how to do this..I've written a code which when i'm trying to use in main its showing the following error:
Error 1 Operator '-' cannot be applied to operands of type 'string' and 'string'
my code is:
public class MyString
{
public string s="SILADITYA";
//public string this[string s]{ get; set; }
public static string operator -(string s1, MyString m)
{
s1 = String.Copy(m.s);
return s1;
}
}
class Program
{
static void Main(string[] args)
{
MyString m = new MyString();
string s1 = s1 - m.s;
}
}
please tell me how can I overload this opoerator
Your code is correct just make this change while calling it from Main
string s1 = string.Empty;
s1 = s1 - m;
It was failing since your operator overload expects a string and MyString parameters and you were supplying String and String
I've created extension methods that can be used like this:
string returnValue = numbers.At(separator, index).Slice();
But I want to create like this:
string returnValue = numbers.At(s => '.').Slice();
Here's the other code.
public class StringParameters
{
public string Text { get; set; }
public int Position { get; set; }
public StringParameters(string text, int position)
{
this.Text = text;
this.Position = position;
}
}
public static StringParameters At(this string text, char c)
{
int index = text.IndexOf(c);
if (index > 0)
{
int index2 = text.IndexOf(c, index + 1);
if (index2 > index)
{
text = text.Substring(index2, text.Length - index2);
}
return new StringParameters(text, index2 + 1);
}
return new StringParameters(null, -1);
}
public static string Slice(this StringParameters parameters)
{
return parameters.Text.Substring(parameters.Position);
}
Edit: I've edited the code and replaced ... with "something here". I do not still get the full idea what it should be there. My expectation is that the method should be more useful by this.
Edit 2: I have now an idea what I want to create with my code. I want to be able to make something like this:
string returnValue = numbers.At(s, i => GetStringParameter()).Slice();
Edit 3: I've edited the code a little bit. It will probably be more clearer now of what I want to achieve.
Edit 4: Corrected a mistake in the code above.
It is not clear for me what are you trying to achieve (start parameter, which you want to replace by function, is not used anywhere in At function), but here is an example extension function with Func<> parameter:
public static StringParameters At(this string text, char c, Func<int> startFunc)
{
int start = startFunc();
int index = text.IndexOf(c);
if (index > 0)
{
int index2 = text.IndexOf(c, index + 1);
if (index2 > index)
{
text = text.Substring(0, text.Length - index2);
}
return new StringParameters(text, index2 + 1);
}
return new StringParameters(null, -1);
}
Usage:
string returnValue = numbers.At(s, () => GetStartIndex()).Slice();
You don't need i => here until you have an argument that you will pass to the Func<> inside At function.
When you call int start = startFunc();, the function you passed as the parameter to At (GetStartIndex() in my example) will be called and its return value will be set to start variable.
I think you want
string returnValue = numbers.At(s, i => GetStringParameter()).Slice();
with the Slice extension method having a signature:
public static string Slice(this StringParameters parameters)
i.e. you want
StringParameters stringParameters = numbers.At(s, i => GetStringParameter());
string returnValue = stringParameters.Slice();
It sounds like you need an overload of your extension method, At, to have a signature like:
public static StringParameters At(this string text, S s, Func<T, U> func)
Where S is the type of the s you're passing in, T is the input to your Func, and U is the output type of the Func.
In the At method, you use your Func like you'd call a method, e.g.
Func<int, string> func = (int)i => i.ToString();
string s = func(123); // s == "123"
I have finally found the solution with the help of Aleksey Shubin and others. The final code looks like this:
public static class Linq
{
public class StringParameters
{
public string Text { get; set; }
public int Position { get; set; }
public StringParameters(string text, int position)
{
this.Text = text;
this.Position = position;
}
}
public static StringParameters At(this string text, Func<char> func)
{
char c = func();
int index = text.IndexOf(c);
if (index > 0)
{
int index2 = text.IndexOf(c, index + 1);
if (index2 > index)
{
text = text.Substring(index2, text.Length - index2);
}
return new StringParameters(text, index2 + 1);
}
return new StringParameters(null, -1);
}
public static string Cut(this StringParameters parameters)
{
return parameters.Text.Substring(parameters.Position);
}
}
This can be used like this:
string returnValue = "132.465..646.656.45".At(() => '.').Cut();
This returns the value of 6.45. It should return the value of 656.45 or probably 132.465, but this is pretty easy. Thanks everyone for your help.
According to the internet when you do
String someString = "" + object1 + object2 + object3;
ToString() is called on each of the objects.
But this is not happening!
This code:
String a = "a" + foo;
String b = "b" + foo.ToString();
Console.WriteLine(a);
Console.WriteLine(b);
Prints:
a
b("key":"foo")
How is it possible?
I made Resharper full cleanup on whole project and it broke code in some place because it removed ToString() in such string concat!! Lost many hours..
Edit:
This problem happened in one of small libraries I was using. I cannot provide very short one-file code that will reproduce this but I have created small project with this library and uploaded to github:
https://github.com/Vistritium/ToStringCSObjectConcat
https://github.com/Vistritium/ToStringCSObjectConcat/blob/master/TestString/Program.cs
The library is 1178 lines long.
This can happen if you have provided an implicit operator converting your class to a string, for instance:
public class Foo
{
public string Key { get; set; }
public string Value { get; set; }
public static implicit operator string(Foo foo)
{
return foo == null ? string.Empty : foo.Value;
}
public override string ToString()
{
var str = string.Empty;
if (!string.IsNullOrEmpty(Key))
{
if (str.Length > 0)
str += ";";
str += ("Key=" + Key);
}
if (!string.IsNullOrEmpty(Value))
{
if (str.Length > 0)
str += ";";
str += ("Value=" + Value);
}
return str;
}
}
In that case:
string a = "a" + new Foo { Key = "foo", Value = "" };
string b = "b" + new Foo { Key = "foo", Value = "" }.ToString();
Debug.WriteLine(a); // Prints "a".
Debug.WriteLine(b); // Prints "bKey=foo
You could also get this effect if you have overloaded the + operator for string and Foo.
Update
From the C# Language Specification, 7.2.2 Operator overloading:
All unary and binary operators have predefined implementations that are automatically available in any expression. In addition to the predefined implementations, user-defined implementations can be introduced by including operator declarations in classes and structs (Section 10.9). User-defined operator implementations always take precedence over predefined operator implementations: Only when no applicable user-defined operator implementations exist will the predefined operator implementations be considered.
That's why the custom logic gets invoked in preference to the standard logic.
I just did this and it is working perfectly
private void button1_Click(object sender, EventArgs e)
{
var o = new x ();
string s = "ff" + o;
Console.WriteLine(s);
}
public class x {
public override string ToString()
{
return "This is string";
}
}
Prints
ffThis is string
Which tells me that you do something wrong. I mean, not as much that you do wrong as much as you expect something different than your objects produce in ToString
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);
}
}