This question already has answers here:
Why I need to use ref keyword in both declaration and Call?
(6 answers)
Closed 4 months ago.
I am attempting to make a method that's used to search for a word in a paragraph that asks the user for the word but I get the error "Argument 2 must be passed with the 'ref' keyword." when trying to call my GetString method from my input.cs. I'm trying to associate the word "find" for the parameter but I'm having a hard time trying to figure this out and would appreciate any help.
Below is my SearchWord method in Program.cs.
public static void SearchWord(Dictionary<string, int> word)
{
string find = "";
string choice = Input.GetString("\nWhat word are you searching for? ", find);
if (word.ContainsKey(choice))
{
PrintKeyValueBar(choice, word[choice]);
string[] sentences = GetSpeech().Split(new char[] {'.',' ',',','!','?',':','\n','\t','\r'});
foreach (string sentence in sentences)
{
if (sentence.Contains(choice))
{
Console.WriteLine(sentence);
}
}
}
else
{
Console.WriteLine($"{choice} is not found.");
}
}
Thank you in advance for the assistance.
EDIT. Adding the GetString method in Input.cs
public static void GetString(string prompt, ref string value)
{
while (true)
{
value = GetInput(prompt);
if (ValidString(prompt))
{
break;
}
Console.WriteLine("That's not right");
}
}
Class instructions state "Use GetString to get the word from the
user!" but when trying to do so I get the error.
I have tried string ref find = "";, ref find = ""; ref string find "";
ref is a keyword in C Sharp to pass a value-type varibale like a ref-type variable to a method call. That means, you are able to change the value of your variable inside the method.
So try Input.GetString("\nWhat word are you searching for? ", ref find);.
Howevery, I don't see the purpose of ref in your code sniped.
Maybe you can post your GetString Method as well!
Related
This question already has answers here:
printing all contents of array in C#
(13 answers)
How does the .ToString() method work?
(4 answers)
Closed 6 years ago.
I am using methods in c#. i returned something but compiler is not printing which i am expecting. It is printing (system.string[]). i dont know why Please help on this.
class Program
{
static void Main(string[] args)
{
string[] sub = subjects();
Console.WriteLine(sub);
}
public static string[] subjects()
{
Console.WriteLine("Please Enter How many Subject Do you Want to input");
int limit = System.Convert.ToInt32(Console.ReadLine());
string[] Subjects = new string[limit];
for (int i = 0; i < limit; i++)
{
Console.WriteLine("Please Enter Subject Name " + i);
Subjects[i] = Console.ReadLine();
}
return Subjects;
}
}
The reason that Program is printing system.string[] is because class string[] does not override ToString method, so the default one is used and the default ToString returns type name, not the "value" inside type.
You can use for example String.Join method to build one string from array of strings and put given delimiter between each string:
Console.WriteLine(String.Join(", ", sub));
Console.WriteLine(sub)
wont show you anything of value (it prints the sub type), since you are not referencing any value of the sub array, e.g sub[0]. Try this:
foreach (string s in sub)
{
Console.WriteLine(s);
}
Console.WriteLine(String.Join(", ", sub));
This question already has an answer here:
String replace not working [duplicate]
(1 answer)
Closed 7 years ago.
I just started learning C# and I am trying to understand how to use the ref and out .
I tried to build the simplest function I could think of but I'm getting error and I can't understand why.
namespace cscheck
{
class Program
{
static void Main(string[] args)
{
string check = "Check noob wallak";
Console.WriteLine(check);
swap(ref check, "noob", "boon");
Console.WriteLine(check);
}
static void swap(ref string origin ,string x, string y)
{
origin.Replace(x, y);
}
}
}
But the results I get are :
Check noob wallak
Check noob wallak
As I understand x and y are passed by value while check passed by reference, but the replace hasn't ouccred and I can figure why.
Because Replace doesn't mutate, it creates a new string. Try:
origin = origin.Replace(x, y);
Replace() returns a string. You must use it as the result as so :
origin = origin.Replace(x, y);
.Replace returns a new string, it does not modify the original. Strings are immutable.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I am just starting to program in C#, so I am a beginner, I've been practicing some codes and I would like your opinion on something.
I have a flying direction for a plane, e.g. ''London - Berlin'' (direction). I want to create a method that will return the first and the last consonant of the plane's starting point (London), and the first and the last consonant of the plane's destination (Berlin). I have written this, so I would like to know if it's ok, or if you have some suggestions:
public class Flight
{
private string direction;
public Flight(string direction)
{
this.direction = direction;
}
public string Consonants()
{
string starting = direction.Split('-')[0];
string destination = direction.Split('-')[1];
string startConsonants = starting.ToUpper().Replace("A", "").Replace("E", "").Replace("I", "").Replace("O", "").Replace("U", "");
string destConsonants = destination.ToUpper().Replace("A", "").Replace("E", "").Replace("I", "").Replace("O", "").Replace("U", "");
return string.Format("{0}{1}-{2}{3}", startConsonants[0].ToString(), startConsonants[startConsonants.Length-1].ToString(), destConsonants[0].ToString(), destConsonants[destConsonants.Length-1].ToString());
}
}
Here are some suggestions:
1 - First point is logical. If you pass the string "London-Lebanon" the output is LN-LN which I consider invalid. With your version, you could also get an error if you pass "London-UAE".
2 - Your constructor is requiring an argument but it is not clear why. I'd suggest you pass the argument to the method that uses it and check if the argument is valid before processing as shown below.
3 - The split is repeated twice for no reason.
4 - You repeat the ToString() several times even on string arguments.
5 - You could define a private method to do the formatting. This prevents errors in case you change the rules.
Here is my version incorporating the above points (except the first):
class Flight
{
public string Consonants(string direction)
{
string[] words = direction.Split('-');
// check if the separator is missing
if (words.Length!=2) return string.Empty; //missing separator error
return string.Format("{0}-{1}", Replacer(words[0]), Replacer(words[1]));
}
private string Replacer(string arg)
{
string abr= arg.ToUpper().Replace("A", string.Empty).Replace("E", string.Empty).Replace("I", string.Empty).Replace("O", string.Empty).Replace("U", string.Empty);
if (abr.Length < 2)
throw new Exception(string.Format("processing error in Replacer input {0} outpur {1}", arg, abr)); // example if you pass: UAE
return string.Format("{0}{1}", abr[0], abr[abr.Length - 1] );
}
}
If you don't mind the upper/lower case distinction then you could use Linq to extract the info required
public string Consonants()
{
string starting = direction.Split('-')[0];
string destination = direction.Split('-')[1];
char[] cs = new char[] {'B','C','D','F','G','H','J','K','L','M','N','P','Q','R','S','T','V','W','X','Z'};
string startFirst = starting.ToUpper().ToCharArray().First(x => cs.Contains(x)).ToString();
string startLast = starting.ToUpper().ToCharArray().Last(x => cs.Contains(x)).ToString();
string destFirst = destination.ToUpper().ToCharArray().First(x => cs.Contains(x)).ToString();
string destLast = destination.ToUpper().ToCharArray().Last(x => cs.Contains(x)).ToString();
return string.Format("{0}{1}-{2}{3}", startFirst, startLast, destFirst, destLast);
}
What I want to do: create a function that takes a string and a single char as input.
The function then shall "flip" every char according to the input char to a lower
or upper case char.
My Problem: I want to do this with a ref string input, therefore the string gets
changed in the function directly without the need to create a new string in the function.
Here is the simplified code:
static void Flip(ref string input)
{
input[0] = 'a';
}
The Problem: Error message -> Property cannot be assigned to, it is read only.
My Question - how can I change that?
What I COULD do is: input = "whatever", but if I want to index through the different
letters in the string with input[i] and change those, it's not possible!
Since I'm new to the "ref" subject - why is this, and how do I fix it?
Thanks!
Strings are immutable that's why its indexer is read only from which you can only read and not write into.
Indexer for string - public char this[int index] { get; }
Instead you should use StringBuilder which is mutable hence its indexer is not read only and you can do in place edits in object.
Indexer for stringBuilder - public char this[int index] { get; set; }
static void Flip(ref StringBuilder input)
{
input[0] = 'a';
}
Refer to this for difference String vs StringBuilder.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am struggling how to use "ref" (to pass argument by reference) in real app. I would like to have simple and mainly meaningful example. Everything I found so far could be easily redone with adding return type to the method.
Any idea someone?
Thanks!
The best example coming in my mind is a function to Swap two variables values:
static void Swap<T>(ref T el1, ref T el2)
{
var mem = el1;
el1 = el2;
el2 = mem;
}
Usage:
static void Main(string[] args)
{
string a = "Hello";
string b = "Hi";
Swap(ref a, ref b);
// now a = "Hi" b = "Hello"
// it works also with array values:
int[] arr = new[] { 1, 2, 3 };
Swap(ref arr[0], ref arr[2]);
// now arr = {3,2,1}
}
A function like this one, cannot be done without the ref keyword.
One possibly corner-case example: Interlocked.Increment. Without passing the variable by reference, there's no way of performing the increment atomically.
I can't say I've used ref very much myself, to be honest - I generally steer clear of the need to return multiple values, and even then out is usually sufficient. Many of the cases where I've seen ref used, it's been due to the author not understanding how arguments are passed in .NET when it comes to reference types.
The TryParse methods built into the framework are typical examples. They use out instead of ref but it is the same semantics, it's just that the caller doesn't need to initialize the value. Example:
int result;
bool isSuccess = int.TryParse("some string", out result);
if (isSuccess)
{
// use the result here
}
As you can see the function returns a boolean indicating whether the operation succeeds but the actual result is returned as out parameter.
public static void Main(string args[])
{
int i=0;
AddSomething(ref i);
AddSomething(ref i);
AddSomething(ref i);
AddSomething(ref i);
string mystr = "Hello";
AddSomeText(ref mystr);
Console.WriteLine(mystr);
Console.WriteLine("i = {0}", i);
}
public static void AddSomeText(ref string str)
{
str+= " World!";
}
public static void AddSomething(ref int ii)
{
ii+=1;
}
One of the most common places I see it, is in Save methods of some frameworks.
The reason is that in many cases it is not actually possible to maintain the same object over a save call, if the object is being serialized to another machine and then comes back as a new instance (perhaps with some extra defaults). In that case you need the ref to make it obvious that the original reference is no longer valid.
As for its NECESSITY, I can't come up with an example where it would be required. Most places out is just fine.
I think a good example would be trampolining.
This is where you take a recursive function and rework it to a method that is repeatidly called on a set of values. The reason being that instead of going into the stack very deeply the stack remains flat because you return after every call instead of calling yourself.
Regards GJ