Changing the entire string in a string builder object - c#

I have the following code:
using System;
using System.Text;
public class Program
{
private static StringBuilder mystrb = new StringBuilder("hello");
public static void Main()
{
mystrb.Clear();
mystrb.Append("chau");
}
}
is there any other way of entirly replacing the string in the string builder, i am looking for a one sentence way of doing it if it exist.

What's wrong with just re-constructing the StringBuilder? The old one will just be garbage collected.
mystrb = new StringBuilder("chau");

The best option is not to instantiate with a default at all. Since you are immediately replacing it with something else, just leave it empty (new StringBuilder()) or null.
private static StringBuilder mystrb;
If you have oversimplified your sample code, then just create a new instance:
mystrb = new StringBuilder("chau");

I think Ian's solution of simply overwriting your object with a new one is the best solution, but if for some reason you don't like that then you could do something like this:
static void StringBuilderReplaceText(StringBuilder sb, string newText)
{
sb.Clear();
sb.AppendLine(newText);
}
I was initially going to simply inherit from the StringBuilder object and add a new Replace extension method but apparently the object is sealed for some reason.
So yea, technically this would allow you to replace the content of a StringBuilder with a single line by later using StringBuilderReplaceText(myStringBuilder, "my new text"); but I really don't see why you'd do this instead of just re-using the constructor.

Related

Text to Speech C#

So I'm just a uni student who's enjoying programming (1st year) and I've decided to try out some new features.
I came across the speech synthesizer and its reallt interesting, but i have one problem.
Say if I said
Console.WriteLine("Hello");
Is there a way that I could get the program to say that without having to add
Console.WriteLine("Hello");
s.Speak("Hello");
?
Like I'm wondering if I am able to have my program speak whatever I type without adding extra code
Cheers
There is no way you could do that. But what you can try is creating a static method that takes a string value and prints "Hello" on to the console and use the TTS engine, like
static void PrintAndSpeak(string message)
{
Console.WriteLine(message);
s.Speak(message);
}
And then use the method inside the entry point:
PrintAndSpeak("Hello");
You could create a method that would take in your string. That method would print and read the message.
Example (pseudocode)
public void writeAndTalk(string message){
Console.WriteLine(message);
s.Speak(message);
}
And you then use the method wherever you like.
You could create a type to do this for you. Something like:
public class TextAndSpeech
{
private readonly WhateverSIs s;
public TextAndSpeech(WhateverSIs s)
{
this.s = s;
}
public Spurt(string message)
{
Console.WriteLine(message);
s.Speak(message);
}
}
I have no idea what type s is that you're using, so replace WhateverSIs with the actual type.
Using it would look something like:
var spurter = new TextAndSpeech(new WhateverSIs());
spurter.Spurt("Hello");
spurter.Spurt("Another thing.");

Formatting a method signature loses indentation

I'm creating a Code Fix which turns the access modifier of detected methods public. The implementation is straightforward: remove all existing access modifiers and add public at the front. Afterwards I replace the node and return the solution.
This however results in a modifier list that looks like this: publicvirtual void Method(). On top of the modifiers being pasted against eachother, that line of code is wrongly indented. It looks like this:
[TestClass]
public class MyClass
{
[TestMethod]
publicvirtual void Method()
{
}
}
So as a solution I format the code instead. Using
var formattedMethod = Formatter.Format(newMethod,
newMethod.Modifiers.Span,
document.Project.Solution.Workspace,
document.Project.Solution.Workspace.Options);
I can format the modifiers but they are still wrongly indented:
[TestClass]
public class MyClass
{
[TestMethod]
public virtual void Method()
{
}
}
I assume this is because of trivia but prepending the formatted method with the original method's leading trivia does not make a difference. I want to avoid formatting the entire document because, well, this isn't an action to format the entire document.
The entire relevant implementation of this Code Fix:
private Task<Solution> MakePublicAsync(Document document, SyntaxNode root, MethodDeclarationSyntax method)
{
var removableModifiers = new[]
{
SyntaxFactory.Token(SyntaxKind.InternalKeyword),
SyntaxFactory.Token(SyntaxKind.ProtectedKeyword),
SyntaxFactory.Token(SyntaxKind.PrivateKeyword)
};
var modifierList = new SyntaxTokenList()
.Add(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
.AddRange(method.Modifiers.Where(x => !removableModifiers.Select(y => y.RawKind).Contains(x.RawKind)));
var newMethod = method.WithModifiers(modifierList);
var formattedMethod = Formatter.Format(newMethod, newMethod.Modifiers.Span, document.Project.Solution.Workspace, document.Project.Solution.Workspace.Options);
var newRoot = root.ReplaceNode(method, formattedMethod.WithLeadingTrivia(method.GetLeadingTrivia()));
var newDocument = document.WithSyntaxRoot(newRoot);
return Task.FromResult(newDocument.Project.Solution);
}
Instead of calling Formatter.Format manually, just put the Formatter.Annotation on your fixed nodes, and the CodeFix engine will call it automatically for you.
The issue is that you need to call Format on the root of the tree, but specify the span of the tree you want formatted, otherwise the formatter will run on just the tree you pass in, with no context from its parent.
The problem was that I had my tests indented in the string representation itself, like this:
var original = #"
using System;
using System.Text;
namespace ConsoleApplication1
{
class MyClass
{
void Method(Nullable<int> myVar = 5)
{
}
}
}";
As you can see there's still a tab between the left margin and the actual code. Apparently the Roslyn formatter can't handle this scenario (which is, admittedly, not a common situation).
In a situation unlike this though, you're probably interested in the formatter which is why I'll accept Kevin's answer.

classes and threading

I have the following code:
public class Search
{
StringBuilder sb = new StringBuilder();
string[] myparams;
public void Start()
{
//Start search threads
for (int i = 0; i < 50; i++)
{
tasks.Add(Task.Factory.StartNew(() =>
{
string text1 = GetFirstRequest(url, myparams);
string text2 = GetFirstRequest(url, myparams);
}, ct, TaskCreationOptions.LongRunning, TaskScheduler.Default));
}
}
private string GetFirstRequest(string url, string[] myparams)
{
//Use stringbuilder to build the complete url with params
//Use webrequest, response and stream to return the url contents
}
private string GetSecondRequest(string url, string[] myparams)
{
//Similar to GetFirstRequest
}
}
For my main form I call:
Search search = new Search();
search.Start();
As you can see from the code above, individual threads are created. However, each thread is calling the same private functions in the Search class in order to access the url.
Is the code thread-safe? Is it better to place the private functions into a separate class and create a class for each thread?
Without seeing the actual code for GetFirstRequest and GetSecondRequest, we can't tell - but the fact that you've got an instance variable of type StringBuilder makes me skeptical. StringBuilder itself isn't thread-safe, and if you're modifying a single object in multiple threads I doubt that you'll get the result you want anyway.
If you're using StringBuilder to build a complete URL, why not just create that StringBuilder in each method? If you don't need to change any of the state of your object, you'll be a long way towards being thread-safe.
Also note that your method has a params parameter but could also access the params instance variable (which would need a different name anyway as params is a keyword in C#). Do you really need that duplication? Why not just use the instance variable from the method?
It feels like this class can be made thread-safe, but almost certainly isn't yet. You need to design it to be thread-safe - which means either avoiding any state mutation, or using appropriate locking. (The former approach is usually cleaner where it's possible.)

how to call non static webmethod form client static method?

I' m trying to do something but I'm not sure if it is allowed in c# here is what I'm tring:
I have a Web Method which is not a static here it is:
[WebMethod]
public Byte[] recStuff(Byte[] recstuffile)
{
myfile = Unzip(muStuff);
return null;
}
and here is my client:
public static XmlDataService.StufServiceSoapClient lhaservice = null;
public static void Autoupload()
{
string fileContents = File.ReadAllText(XMLStuffName);
string text = fileContents;
byte r2 = Zip(text);
lhaservice.recStuff(r2);
}
I am getting Error that:
Object reference not set to an instance of an object.
what can I do here?
It is very logical. lhaservice = null. Initialize it.
In any case you have to instantiate lhaservice first before you use it in your (static) constructor:
lhaservice = new XmlDataService.StufServiceSoapClient();
...but unless you show all your relevant code we don't really know for sure what the problem could be in your code.
Note: avoid static classes and operations if they don't make any sense. Make them non-static and create an instance before using the Autoupload operation. Your code will become more flexible and testable. So you might want to rethink your code.

C# Delegates & guid.newguid()

I just started using C# this afternoon, so be a little gentle.
Currently I am working on a type of "template engine" where one of the callbacks needs to generate a globally unique ID. I am using delegates to manage the callbacks.
Currently the code looks like this (though I have also tried an anonymous function & returning NewGuid directly w/o a variable):
static string UID(List<string> p)
{
string s = Guid.NewGuid().ToString();
return s;
}
Which, when called directly, works fine. However if I try to call it via the delegate (added to a StringDictionary via addCallback("generate UID", new CallbackWrapper(UID))), the program will generate the same GUID regardless of how many times I duplicate it; even though calling the method directly both before & after the event occurs results in a unique ID as expected. I'v
No doubt it's just something simple I've missed, inevitably stemming from me being relatively inexperienced at C#.
Any help would be appreciated.
Thanks.
Well, I've now tried Dictionary with the same result.
CallbackWrapper is just the delegate, it's defined like this:
delegate string CallbackWrapper(List<string> parameters);
The remainder of the work is done in another class, which looks like this:
class TemplateParser
{
private Dictionary<string, CallbackWrapper> callbackMap;
public TemplateParser(string directivePrefix, string directiveSuffix)
{
...
callbackMap = new Dictionary<string,CallbackWrapper>();
}
public TemplateParser() : this("<!-- {", "} -->") {}
{
callbackMap.Add(name, callback);
}
public string parse(string filename)
{
...
string replacement =
callbackMap[directiveName](new List<string>(parameters.Split(new string[] { ";", " " }, StringSplitOptions.RemoveEmptyEntries));
...
}
}
I've stripped out the majority of the string handling code to save some space.
The issue is in your calling code, not in the code itself, nor in the delegate.
Using delegates here definitely works if called correctly.
Furthermore, your code can be slightly simplified:
static string UID(List<string> p)
{
return Guid.NewGuid().ToString();
}
(The variable is utterly redundant.)
use delegate.invoke
The difference between direct function call and delegate.invoke is here
http://social.msdn.microsoft.com/Forums/en/csharplanguage/thread/f629c34d-6523-433a-90b3-bb5d445c5587
StringDictionary will automatically cast your CallbackWrapper to a string, meaning it will only run once and store the output of CallbackWrapper.ToString(). This is probably not what you want.
Try using Dictionary<string, CallbackWrapper> instead.

Categories