Overwriting an extension method C# - 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.

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".

C# Generic Extension Method Compiles But Unusable?

I am trying to write a generic extension method for adding a fixed matrix to an "elastic" matrix. The extension method compiles and (I assume) its code works fine in a regular method. Knowing I'll be using this function a lot for various types, I would much prefer to figure this problem out instead of limping along with a band-aid:
public void AddMatrix<T>(this List<T[]> MyList, T[,] Matrix)
{
if (MyList == null) throw new ArgumentNullException("MyList");
if (Matrix == null) throw new ArgumentNullException("Matrix");
for (int i = 0; i < Matrix.GetLength(0); i++)
{
T[] aLine = new T[Matrix.GetLength(1)];
for (int j = 0; j < Matrix.GetLength(1); j++)
aLine[j] = Matrix[i, j];
MyList.Add(aLine);
}
}
public void testAddMatrix()
{
List<string[]> aMyBigMatrix = new List<string[]>();
string[,] aSmallerMatrix =
{
{
"foo",
"bar",
"what"
}
};
aMyBigMatrix.AddMatrix(aSmallerMatrix); // .AddMatrix is not showing up here in Intellisense?
}
From MSDN:
To defining and call the extension method
Define a static class to contain the extension method. The class must be visible to client code.
Implement the extension method as a static method with at least the same visibility as the containing class.
The first parameter of the method specifies the type that the method operates on; it must be preceded with the this modifier.
Your method is not static (2.).
You are writing an extension method, AddMatrix<T> needs to be static.
Extension methods have to be static.
Extension methods must be static.
Change it to:
public static void AddMatrix(this List MyList, T[,] Matrix)
And make sure the class is static too.
As everyone is quick to point out, extension methods must be static.
When I attempted to duplicate your error, I got a compiler error "Extension method must be static", so it seems strange to me that you report that your code compiles. When you try to compile it, look at the Error List to see if it is in fact empty. I suspect you will find an error message that you had not noticed before. If you are able to see the compiler errors, your mistakes of this nature will be easy to identify and fix.

send a String array as parameter to a function

I have a function in a class called Function, like below:
public int SearchedRecords(String [] recs)
{
int counter = 0;
String pat = "-----";
String[] records = recs;
foreach (String line in records)
{
if (line.Contains(pat) == true)
{
counter++;
}
}
return counter;
}
And I am calling this method from my main class this way:
String [] file = File.ReadAllLines("C:/Users.../results.txt");
int counter = Function.SearchedRecords( []file);
But I get an error saying:
;expected
What is wrong?
Another question: The function above is counting from a file all the lines with the pattern ----- in them (even if with more dashes, or if the line has some chars before or after the dashes). Am I right?
It's something like the patterns in Java so maybe there is an other way.
Can you enlighten me?
Remove the [] from your parameter.
e.g.
int counter = Function.SearchedRecords(file);
And yes, your assumption about the behavior of the Contains method is correct - you'll match any line containing five consecutive dashes, regardless of what characters are before or after them.
If you want to parse for exactly five dashes, with nothing before or after them I suggest looking into the RegEx class (regular expressions).
Change
int counter = Function.SearchedRecords( []file);
to
int counter = Function.SearchedRecords(file);
and yes, this will work, for that string.
However Contains is case sensitive, if you were matching on a name, or another string with alphabetic characters, the case would have to be identical to match e.g. line.Contains("Binary Worrier") will not match a string "Hello binary worrier".
Also, reading the entire file into memory is fine if you know that the file will always be small, this method gets less efficient the larger the file.
Better to always use something like System.IO.StreamReader or System.IO.File.ReadLines (available in .Net 4 and later), these allow you to consume the file one line at a time. e.g.
using (var reader = new System.IO.StreamReader("MyFile.txt"))
{
while(!reader.EndOfStream)
{
string line = reader.ReadLine();
if (line.Contains(pattern))
counter++;
}
}
Change it to
int counter = Function.SearchedRecords(file);
Remove '[]' from a method call. Yes, your function seems to count what you want.
First of all you need to create an instance of function class and then run the function. Hope following code helps
Function fb = new Function();
int counter = fb.SearchedRecords(file);
Right now, you are using SearchRecords as an static function of a static class which doesn't require instantiation.
You can do this in a shorter way using LINQ:
int counter = file.Count(line => line.Contains("-----"));

Dealing with Tokens

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.

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