Dealing with Tokens - c#

I have the following assignment for homework.
Requirements
Design a class called TokenGiver with the following elements:
a default constructor, a parametrized constructor that takes an int
a method that adds a specified number of tokens to the number of tokens
a method that subtracts exactly ONE token from your number of tokens
a method that returns the number of tokens in your object
Other Requirements:
create a TokenGiver object
store 10 tokens in it
ask the TokenGiver object how many tokens it has and display the result
take 2 tokens out of the TokenGiver object
ask the TokenGiver object how many tokens it has and display the result
Question
Is there a better way to subtract two tokens at once from my Main() method, or is calling the GetToken() method twice the only way?
Code Snippet:
using System;
class Program
{
const int NUM_TOKENS = 10;
static void Main()
{
TokenGiver tokenMachine = new TokenGiver(NUM_TOKENS);
Console.WriteLine("Current number of tokens = {0}",
tokenMachine.CountTokens());
tokenMachine.GetToken();
tokenMachine.GetToken();
Console.WriteLine("New number of tokens = {0}",
tokenMachine.CountTokens());
Console.ReadLine();
}
}
class TokenGiver
{
private int numTokens;
public TokenGiver()
{
numTokens = 0;
}
public TokenGiver(int t)
{
numTokens = t;
}
public void AddTokens(int t)
{
numTokens += t;
}
public void GetToken()
{
numTokens--;
}
public int CountTokens()
{
return numTokens;
}
}

There is a better way, as Ed said. But with your assignment saying that you need a method to subtract exactly 1 Token, you are doing it how you should.
public void GetToken(int t)
{
numTokens -= t;
}
then you would could call GetToken(2);

Well, whether or not there is a better way to extract two tokens than by calling GetToken twice seems irrelevant because one of your requirements is:
(the class shall have) a method that subtracts exactly ONE token from your number of tokens
So, it seems you are stuck with two calls. Since this is a highly contrived assignment you may as well just stick to the requirements. If you really want to learn something start your own personal project. :)
Also, as an aside, you can chain constructors in C#. So this:
public TokenGiver()
{
numTokens = 0;
}
public TokenGiver(int t)
{
numTokens = t;
}
...becomes...
public TokenGiver() : this(0) { }
public TokenGiver(int t)
{
numTokens = t;
}

Given the requirements, you have to call GetToken twice... But of course it would be possible to create an overload for this method that would take the number of tokens to subtract as a parameter.
As a side note : GetToken is a poorly choosed name... usually a method whose name starts with "Get" is expected to return something. You could call it "TakeToken" instead, or something similar

His requirements say to create and THEN add the 10 tokens. You call the constructor with a 10 -- call the constructor with void and then add the ten. I believe this was the assignment.

To simply answer your question, what's wrong with tokenMachine.AddTokens(-2)? Given the requirements, it doesn't seem to be out of the question. The .NET framework also commonly uses this construction as well (e.g. DateTime.AddDays() takes a negative number to subtract).
However, a bad instructor may mark you off for this, using the argument that "[he intended to specify that] the machine can only dispense one token at a time", so it may be best to clarify the specifications.

Related

Call random method directly instead of using a lot of if-statements, C#

Relative newcomer to c# here.
Let’s say I have 50 different methods a1(), a2(), … a50() and I want to call a random one. One way to do it is of course to generate a random int, nr, between 1 and 50 and then use a lot of if statements like if(nr == 1){
a1()
} and so on. Quite cumbersome - can I do something smarter?
Is it for example possible to do something along the lines of creating a string which is initially only “a” and then adding nr as a string and then calling that string as method? Like this:
Public void RandomMethod()
{
nr = Random.Range(1,51);
string = ‘a’ + nr.tostring();
string();
}
I know this doesn’t work, but something like this instead of my first idea would save me hundreds of lines of code
Any response is appreciated 😊
One option would be to put your functions into a collection, say a List for example. Then you could randomly index into that collection to get a random function to call. You would generate a random index between 0 and the length of the List minus 1. This could apply generally to any number of functions then (50 or otherwise).
To do exactly what you asked (and, I have no clue why you'd want to), consider something like this:
Create a delegate that matches the call signature of all of your methods (they all have to have the same call signature or ... I really can't imagine what you'd want to do if they didn't). You could use an Action or Func declaration, but I'm going to make it clear here:
public delegate void SomeMethod(int i);
Then write your 50 methods. All their call signatures will match the delegate:
public static void Method1(int i) { System.Console.WriteLine($"{nameof(Method1)}: {i}"); }
public static void Method2(int i) { System.Console.WriteLine($"{nameof(Method2)}: {i}"); }
public static void Method3(int i) { System.Console.WriteLine($"{nameof(Method3)}: {i}"); }
public static void Method4(int i) { System.Console.WriteLine($"{nameof(Method4)}: {i}"); }
// ...
public static void Method50(int i) { System.Console.WriteLine($"{nameof(Method50)}: {i}"); }
Then create an array of delegates:
public static SomeMethod[] Methods = new SomeMethod[]
{
Method1,
Method2,
Method3,
Method4,
//...
Method50,
};
And then a method that picks 1 or more from the list at random and runs them:
public void Run5RandomMethods()
{
Random random = new Random();
for(int i = 0; i < 5; i++)
{
var randNumber = random.Next(50);
var method = Methods[randNumber];
method.Invoke(i);
}
}
Note: this is untested, I'm not going to create 50 dummy methods for you. If you find an issue, comment below and I'll fix the code
By the way, what you show in your question (composing the name of the method by concatenating a string and the string representation of a number) is doable using a technology known as Reflection. Let me know if you really want to do that.
So, assuming we have fifty methods that all have a signature like
void SomeMethod()
{
...
}
You could declare an array like below, this is an array of Action delegates
var methods = new Action[]
{
SomeMethod,
SomeOtherMethod,
() => _ = SomeFunctionWithAHardcodedParameter("Wibble"),
...
}
Then you could call a random method by doing,
method[Random.Next(methods.Length)]();
First off, I just want to say something similar to what others have already said: you should readdress whether you need 50 methods named a1(), a2(), ..., a50(), and rethink what the problem you're trying to solve is (which you haven't provided enough information for us to help you with).
If that was hyperbole, try to avoid doing that; it may muddy the responses to solve a perceived problem ("why do you have 50 poorly-named methods?") instead of your actual problem ("can I execute a randomly selected method?" <- still a weird question, but who am I to judge...).
That out of the way, you can use something like Reflection. This can be "dangerous" and expensive when executing, so use with caution... or better yet don't use it, but be aware of it, because it can lead you to think Reflection is the answer to problems you don't actually have.
Anyway, you can:
// have an instance of an object
var obj = new ClassName();
// get all the methods of the object
var methodInfos = typeof(ClassName).GetMethods();
// filter them somehow
var filteredMethodInfos = methodInfos.Where(m => Regex.IsMatch(m.Name, #"\a[\d]{1,2}")).ToArray();
// get a random one and invoke it
var rnd = new Random();
filteredMethodInfos[rnd.Next(filteredMethodInfos.Length)].Invoke(obj, null);
I haven't tested this, but it should in theory work.
But again: don't use reflection if you don't have to. There's probably an issue with your root question (as Tim Schmelter said, this is an "XY-problem") if your answer is "randomly execute 1 of 50 methods".

How can i call upon only the return variable in a method?

I'm new and struggling with object orientated programming. I want to use only the return value in my third method 'tableinfo' however i don't know how to transfer only this value to the other methods, without running the first two methods again. All i want to do is transfer only the value that the user enters over to the third method and not have to put in the values two times each, this is the only way i know to get the value across and i would really appreciate if anyone could help me to just get the return value. This code is a tiny snippet of what i'm trying to do and it's purpose is not important, i just wanted to create an example to try and allow people to understand what i mean.
Thank you in advance!
class Program
{
static void Main(string[] args)
{
TableOrder TO = new TableOrder();
TO.TableNumber();
TO.NumberOfPartons();
TO.tableinfo();
}
}
class TableOrder
{
int tablenumber;
string inputtablenumber;
int numberAtTable;
string inputNumberAtTable;
public int TableNumber()
{
Console.Write("please enter the table number:");
inputtablenumber = Console.ReadLine();
tablenumber = int.Parse(inputtablenumber);
return tablenumber;
}
public int NumberOfPartons()
{
Console.Write("please enter how many people are seated: ");
inputNumberAtTable = Console.ReadLine();
numberAtTable = int.Parse(inputNumberAtTable);
return numberAtTable;
}
public void tableinfo()
{
int tablenum = TableNumber();
Console.Write(tablenumber + 1);
int patrons = NumberOfPartons();
Console.WriteLine(numberAtTable + 1);
}
}
It looks like you might be confused on the difference between methods, properties, and fields. Your function TableNumber() might be more accurately called AskUserForTableNumber() or GetTableNumberFromInput(). Something like that. You are also both setting a member field and returning the value. So there are a bunch of ways you could store and retrieve that value. If the member field tablenumber was marked as public, you could access it. Or in your main function you could do this:
int tablenum=TO.TableNumber();
and then reuse that value.
Another odd thing you are doing is storing the input string as a member field. If you don't need to reference that string again, then there's no reason for that to be a member of the TableOrder object, it could be a local variable to the function that is doing the input.
But it seems like you are trying to use TableOrder.TableNumber like a property. And that very well may be the right thing to do, but not in the way that you are doing it. Here is a (sort of fancy) way of doing something similar, which also uses a concept of lazy-loading...
class TableOrder
{
private int? _tablenumber;
public int TableNumber
{
get
{
return _tablenumber ?? (_tablenumber=GetTableNumberFromInput());
}
set
{
_tablenumber = value;
}
}
private static int GetTableNumberFromInput()
{
Console.Write("please enter the table number:");
string inputtablenumber = Console.ReadLine();
return int.Parse(inputtablenumber);
}
//(and so on for other member properties)
}
This way, the first time you try to access table number, it will ask the user for the value. Afterward, you will already have the value, so it will not ask again. Note that this type of approach is not really necessary, and is mainly useful for waiting to load a value until you need to use that value. Instead you could just do something like: TableOrder.TableNumber = GetTableNumberFromInput();
First of all, you can remove the calls in your main since the method tableinfo() will call them:
class Program
{
static void Main(string[] args)
{
TableOrder TO = new TableOrder();
TO.tableinfo();
}
}
Second, you want to use the class variables that you already declared,
The returned value of the two functions are stored inside those and you can output them with Write.
public void tableinfo()
{
tablenumber = TableNumber();
Console.Write(tablenumber + 1);
numberAtTable = NumberOfPartons();
Console.WriteLine(numberAtTable + 1);
}
In the scope of this function, the return values (return numberAtTable and return tablenumber) don't exist anymore, they are stored in whats left of the called functions.

Make a list readonly in c#

I have this example code. What I want to do is to make it so that the "Nums" value can only be written to using the "AddNum" method.
namespace ConsoleApplication1
{
public class Person
{
string myName = "N/A";
int myAge = 0;
List<int> _nums = new List<int>();
public List<int> Nums
{
get
{
return _nums;
}
}
public void AddNum(int NumToAdd)
{
_nums.Add(NumToAdd);
}
public string Name { get; set; }
public int Age { get; set; }
}
}
Somehow, I've tried a bunch of things regarding AsReadOnly() and the readonly keyword, but I can't seem to get it to do what I want it to do.
Here is the sample of the code I have to access the property.
Person p1 = new Person();
p1.Nums.Add(25); //access 1
p1.AddNum(37); //access 2
Console.WriteLine("press any key");
Console.ReadLine();
I really want "access 1" to fail, and "access 2" to be the ONLY way that the value can be set. Thanks in advance for the help.
√ DO use ReadOnlyCollection, a subclass of ReadOnlyCollection,
or in rare cases IEnumerable for properties or return values
representing read-only collections.
The quote from this article.
You should have something like this:
List<int> _nums = new List<int>();
public ReadOnlyCollection<int> Nums
{
get
{
return _nums.AsReadOnly();
}
}
In general, collection types make poor properties because even when a collection is wrapped in ReadOnlyCollection, it's inherently unclear what:
IEnumerable<int> nums = myPerson.Nums;
myPerson.AddNum(23);
foreach(int i in nums) // Should the 23 be included!?
...
is supposed to mean. Is the object returned from Nums a snapshot of the numbers that existed when it called, is it a live view?
A cleaner approach is to have a method called something like GetNumsAsArray which returns a new array each time it's called; it may also be helpful in some cases to have a GetNumsAsList variant depending upon what the caller will want to do with the numbers. Some methods only work with arrays, and some only work with lists, so if only one of the above is provided some callers will have to call it and then convert the returned object to the required type.
If performance-sensitive callers will be needing to use this code a lot, it may be helpful to have a more general-purpose method:
int CopyNumsIntoArray(int sourceIndex, int reqCount, ref int[] dest,
int destIndex, CopyCountMode mode);
where CopyCountMode indicates what the code should do the number of items available starting at sourceIndex is greater or less than reqCount; the method should either return the number of items that were available, or throw an exception if it violated the caller's stated expectations. Some callers might start by create and passing in a 10-item array but be prepared to have the method replace it with a bigger array if there are more than ten items to be returned; others might expect that there will be exactly 23 items and be unprepared to handle any other number. Using a parameter to specify the mode will allow one method to service many kinds of callers.
Although many collection authors don't bother including any method that fits the above pattern, such methods can greatly improve efficiency in cases where code wants to work with a significant minority of a collection (e.g. 1,000 items out of a collection of 50,000). In the absence of such methods, code wishing to work with such a range must either ask for a copy of the whole thing (very wasteful) or request thousands of items individually (also wasteful). Allowing the caller to supply the destination array would improve efficiency in the case where the same method makes many queries, especially if the destination array would be large enough to be put on the large object heap.

Overwriting an extension method C#

I am using RestSharp to create http requests to a webservice. One of the parameters length is very long running >100 K characters, so I figured I'll need to use the POST method (because of limitations on length of query string with GET). However, when I tried doing so I got an exception that the uri is too long. I downloaded their source code to find out why. Take a look at the following code:
querystring.AppendFormat("{0}={1}", p.Name.UrlEncode(), p.Value.UrlEncode());
Now the UrlEncode() method is an extension method available in StringExtensions.cs class and it's implementations is like so:
public static string UrlEncode(this string input)
{
return Uri.EscapeDataString(input);
}
The problem is that Uri.EscapeDataString cannot process a string more than 65519 characters (see post - Uri.EscapeDataString() - Invalid URI: The Uri string is too long)
My problem can be solved if the UrlEncode extension method was implemented like this
public static string UrlEncode(this string input)
{
int limit = 65520;
StringBuilder sb = new StringBuilder();
int loops = input.Length / limit;
for (int i = 0; i <= loops; i++)
{
if (i < loops)
{
sb.Append(Uri.EscapeDataString(input.Substring(limit * i, limit)));
}
else
{
sb.Append(Uri.EscapeDataString(input.Substring(limit * i)));
}
}
return sb.ToString();
}
The issue is that I DON'T want to HAVE to modify the source code. Is there a way I can write my own extension method in MY source code such that when the third party code is trying to invoke UrlEncode() it ignores it's own extension method and instead calls my extension method??
Any help is much appreciated. Thanks.
Thankfully, there's no way that I know of. The extension method s.UrlEncode() is basically syntactic sugar for
StringExtensions.UrlEncode(s);
Since this method is static, there's no way to "override" it. In addition, it's bound to that method at compile time, so there's no way to redirect it to a different method at run time.
It should NOT be allowed, either. If it were, You could create an "override" it to format your C drive!.
If YOU want to use a different version, you could create a new extension method with a different name, or figure out a way to shorten your parameter lengths. :)
one solution would be to extend the existing Uri class with hiding through inheritance - you should inherit the existing Uri class and then override with the new operator the desired method. This way you will change the default behaviour without modifying original code. Code example:
public class A
{
public int Get1()
{
return 1;
}
public int Get2()
{
return 100;
}
}
public class B : A
{
// override A's Get1
public new int Get1()
{
return 2;
}
}
and the output of the call:
var b = new B();
System.Console.WriteLine(string.Format("{0} - {1}", b.Get1(), b.Get2()));
would be:
2 - 100
and not 1 - 100!
Hope this helps.
Regards,
P.
Check out this answer to see how to do a POST using RestSharp. The payload goes in the message body, not in the query string.

C#: Returning 'this' for method nesting?

I have a class that I have to call one or two methods a lot of times after each other. The methods currently return void. I was thinking, would it be better to have it return this, so that the methods could be nested? or is that considerd very very very bad? or if bad, would it be better if it returned a new object of the same type? Or what do you think? As an example I have created three versions of an adder class:
// Regular
class Adder
{
public Adder() { Number = 0; }
public int Number { get; private set; }
public void Add(int i) { Number += i; }
public void Remove(int i) { Number -= i; }
}
// Returning this
class Adder
{
public Adder() { Number = 0; }
public int Number { get; private set; }
public Adder Add(int i) { Number += i; return this; }
public Adder Remove(int i) { Number -= i; return this; }
}
// Returning new
class Adder
{
public Adder() : this(0) { }
private Adder(int i) { Number = i; }
public int Number { get; private set; }
public Adder Add(int i) { return new Adder(Number + i); }
public Adder Remove(int i) { return new Adder(Number - i); }
}
The first one can be used this way:
var a = new Adder();
a.Add(4);
a.Remove(1);
a.Add(7);
a.Remove(3);
The other two can be used this way:
var a = new Adder()
.Add(4)
.Remove(1)
.Add(7)
.Remove(3);
Where the only difference is that a in the first case is the new Adder() while in the latter it is the result of the last method.
The first I find that quickly become... annoying to write over and over again. So I would like to use one of the other versions.
The third works kind of like many other methods, like many String methods and IEnumerable extension methods. I guess that has its positive side in that you can do things like var a = new Adder(); var b = a.Add(5); and then have one that was 0 and one that was 5. But at the same time, isn't it a bit expensive to create new objects all the time? And when will the first object die? When the first method returns kind of? Or?
Anyways, I like the one that returns this and think I will use that, but I am very curious to know what others think about this case. And what is considered best practice.
The 'return this' style is sometimes called a fluent interface and is a common practice.
I like "fluent syntax" and would take the second one. After all, you could still use it as the first, for people who feel uncomfortable with fluent syntax.
another idea to make an interface like the adders one easier to use:
public Adder Add(params int[] i) { /* ... */ }
public Adder Remove(params int[] i) { /* ... */ }
Adder adder = new Adder()
.Add(1, 2, 3)
.Remove(3, 4);
I always try to make short and easy-to-read interfaces, but many people like to write the code as complicated as possible.
Chaining is a nice thing to have and is core in some frameworks (for instance Linq extensions and jQuery both use it heavily).
Whether you create a new object or return this depends on how you expect your initial object to behave:
var a = new Adder();
var b = a.Add(4)
.Remove(1)
.Add(7)
.Remove(3);
//now - should a==b ?
Chaining in jQuery will have changed your original object - it has returned this.
That's expected behaviour - do do otherwise would basically clone UI elements.
Chaining in Linq will have left your original collection unchanged. That too is expected behaviour - each chained function is a filter or transformation, and the original collection is often immutable.
Which pattern better suits what you're doing?
I think that for simple interfaces, the "fluent" interface is very useful, particularly because it is very simple to implement. The value of the fluent interface is that it eliminates a lot of the extraneous fluff that gets in the way of understanding. Developing such an interface can take a lot of time, especially when the interface starts to be involved. You should worry about how the usage of the interface "reads"; In my mind, the most compelling use for such an interface is how it communicates the intent of the programmer, not the amount of characters that it saves.
To answer your specific question, I like the "return this" style. My typical use of the fluent interface is to define a set of options. That is, I create an instance of the class and then use the fluent methods on the instance to define the desired behavior of the object. If I have a yes/no option (say for logging), I try not to have a "setLogging(bool state)" method but rather two methods "WithLogging" and "WithoutLogging". This is somewhat more work but the clarity of the final result is very useful.
Consider this: if you come back to this code in 5 years, is this going to make sense to you? If so, then I suppose you can go ahead.
For this specific example, though, it would seem that overloading the + and - operators would make things clearer and accomplish the same thing.
For your specific case, overloading the arithmetic operators would be probably the best solution.
Returning this (Fluent interface) is common practice to create expressions - unit testing and mocking frameworks use this a lot. Fluent Hibernate is another example.
Returning a new instance might be a good choice, too. It allows you to make your class immutable - in general a good thing and very handy in the case of multithreading. But think about the object creation overhead if immutability is of no use for you.
If you call it Adder, I'd go with returning this. However, it's kind of strange for an Adder class to contain an answer.
You might consider making it something like MyNumber and create an Add()-method.
Ideally (IMHO), that would not change the number that is stored inside your instance, but create a new instance with the new value, which you return:
class MyNumber
{
...
MyNumber Add( int i )
{
return new MyNumber( this.Value + i );
}
}
The main difference between the second and third solution is that by returning a new instance instead of this you are able to "catch" the object in a certain state and continue from that.
var a = new Adder()
.Add(4);
var b = a.Remove(1);
var c = a.Add(7)
.Remove(3);
In this case both b and c have the state captured in a as a starting point.
I came across this idiom while reading about a pattern for building test domain objects in Growing Object-Oriented Software, Guided by Tests by Steve Freeman; Nat Pryce.
On your question regarding the lifetime of your instances: I would exspect them to be elligible for garbage collection as soon as the invocation of Remove or Add are returning.

Categories

Resources