Does MS Test provide a default value equals comparison? - c#

I want to test for example
int orderId = myRepository.SubmitOrder(orderA);
orderB = myRepository.GetOrder(orderId);
Assert.AreEqual(orderA, orderB); // fail
Obviously I need a value comparison here, but I don't want to have to provide an overridden Equals implementation for all of my classes purely for the sake of testing (it wouldn't be of any use in the rest of the app).
Is there a provided generic method that just checks every field using reflection? Or if not, it is possible to write my own?
EDIT: As it seems people are kind of missing the point. I don't want to have to write my own comparison logic. That would require hundreds of lines of extra code. I'm looking for something like a generic
bool ContainSameValues<T>(T t1, T t2)
method which recursively uses reflection to pull out all the values in T.
FURTHER EDIT: Since it doesn't appear there is any built in support for doing something like this, you can see my (failed) attempt at writing my own here

Easiest thing to do is compare the "primitive" fields yourself:
Assert.AreEqual(orderA.ID, orderB.ID);
Assert.AreEqual(orderA.CustomerID, orderB.CustomerID);
Assert.AreEqual(orderA.OrderDate, orderB.OrderDate);

As the Assert class is static, it is impossible to create extension methods on it (as an instance is required). However, why not create a wrapper for the Assert class, where you can perform custom assertions?
e.g:
public static class MyAssertions
{
public static void AreOrdersEqual(Order a, Order b)
{
if (!OrdersAreEqual) // your comparison logic here
Assert.Fail("Orders arent equal");
}
}
Then in your test:
MyAssertions.AreOrdersEqual(orderA, orderB)

You'll have to implement IComparable(or ICompare?) in the Order class.method.

Related

How can I add another argument to CompareTo method?

How can I add another argument to the CompareTo method so I can implement a switch statement to allow my program to select what the CompareTo method will be comparing?
Current I'm doing:
public int CompareTo(Employee other)
{
return name.CompareTo(other.name);
}
What I want to do:
public int CompareTo(Employee other, string choice)
{
switch(choice)
{
case "name":
return name.CompareTo(other.name);
case "number"
return number.CompareTo(other.number);
}
return name.CompareTo(other.name);
}
I assume you're asking how you can extend the functionality of existing classes that you can't modify (otherwise you could directly edit the class itself), and if that's the case, I'd recommend making an extension method as such:
public static class EmployeeExtensions {
public static int CompareTo(this Employee baseEmployee, Employee other, string choice){
... code ....
return 0;
}
}
This will then allow you to extend the compare to functionality, and call this from wherever you require it. You need to put the extension method in its own static class.
You can call it by going:
Employee a = new Employee(...);
Employee b = new Employee(...);
a.CompareTo(b, "args");
Assuming the extension class has been imported where you are trying to use it. This is usually the way C# allows for extending functionality of classes you do not have access to. Although if you do have access to the class I'd recommend editing the class itself and making a new method (you may be able to override, but if they provide distinct functionality you'll need to write two methods, in this case code duplication is ok).
This doesn't apply if you're actually trying to change the default equality members, and if that's the case, you can't add your own argument and have it still work with existing infrastructure such as list sorting, so I'd recommend re-evaluating your problem if you 'want to add an argument to equals' for example.
If you're trying to change the way objects compare (objects implementing IComparable), then make your own IComparer, and use that to do the comparing, don't try and change the way CompareTo is done on the class, as the default behavior of Compare (with arguments as is) is useful. I'm also not saying don't implement IComparable (rather than making a IComparer) if it makes sense and you have access to the class then use an IComparable, but that won't allow you to change the arguments of the inherited compare method.

Should I be using IEquatable to ease testing of factories?

I often work with classes that represent entities produced from a factory.
To enable easy testing of my factories easily I usually implement IEquatable<T>, whilst also overriding GetHashCode and Equals (as suggested by the MSDN).
For example; take the following entity class which is simplified for example purposes. Typically my classes have a bunch more properties. Occasionally there is a also collection, which in the Equals method I check using SequenceEqual.
public class Product : IEquatable<Product>
{
public string Name
{
get;
private set;
}
public Product(string name)
{
Name = name;
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
Product product = obj as Product;
if (product == null)
{
return false;
}
else
{
return Equals(product);
}
}
public bool Equals(Product other)
{
return Name == other.Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
This means I can then do simple unit tests like so (assuming the constructor is tested elsewhere).
[TestMethod]
public void TestFactory()
{
Product expected = new Product("James");
Product actual = ProductFactory.BuildJames();
Assert.AreEqual(expected, actual);
}
However this raises a number of questions.
GetHashCode isn't actually used but I've spent time implementing it.
I rarely actually want to use Equals in my actual application beyond testing.
I spend more time writing more tests to ensure the Equals actually works correctly.
I now have another three methods to maintain, e.g. add a property to the class, update methods.
But, this does give me a very neat TestMethod.
Is this an appropriate use of IEquatable, or should I take another approach?
Whether this is a good idea or not really depends on what kind of type your factory creates. There are two kinds of types:
Types with value semantics (value types for short) and
Types with reference semantics (reference types for short.)
In C# it is common to use struct for value types and class for reference types, but you do not have to, you may use class for both. The point is that:
Value types are meant to be small, usually immutable, self-contained objects whose main purpose is to contain a certain value, while
Reference types are objects that have complex mutable state, possibly references to other objects, and non-trivial functionality, i.e. algorithms, business logic, etc.
If your factory is creating a value type, then sure, go ahead and make it IEquatable and use this neat trick. But in most cases, we don't use factories for value types, which tend to be rather trivial, we use factories for reference types, which tend to be rather complex, so if your factory is creating a reference type, then really, these kinds of objects are only meant to be compared by reference, so adding Equals() and GetHashCode() methods is anywhere from misleading to wrong.
Take a hint from what happens with hash maps: the presence of Equals() and GetHashCode() in a type generally means that you can use an instance of this type as a key in a hash map; but if the object is not an immutable value type, then its state may change after it has been placed in the map, in which case the GetHashCode() method will start evaluating to something else, but the hash map will never bother re-invoking GetHashCode() in order to re-position the object in the map. The result in such cases tends to be chaos.
So, the bottom line is that if your factory creates complex objects, then you should perhaps take a different approach. The obvious solution is to invoke the factory and then check each property of the returned object to make sure they are all as expected.
I could perhaps propose an improvement to this, though beware that I just thought of it, I have never tried it, so it may and may not turn out to be a good idea in practice. Here it is:
Your factory presumably creates objects that implement a particular interface. (Otherwise, what's the point of having a factory, right?) So, you could in theory stipulate that newly created instances of objects that implement this interface should have certain properties initialized to a particular set of values. This would be a rule imposed by the interface, so you could have some function tied to the interface which checks whether this is true, and this function could even be parametrized with some hint as to expect different initial values under different circumstances.
(Last I checked, in C# a method tied to an interface was usually an extension method; I do not remember off the top of my head whether C# allows static methods to be part of an interface, or whether the designers of C# have yet added to the language something as neat and elegant as the default interface methods of Java.)
So, with an extension method, it could perhaps look like this:
public boolean IsProperlyInitializedInstance( this IProduct self, String hint )
{
if( self.Name != hint )
return false;
//more checks here
return true;
}
IProduct product = productFactory.BuildJames();
Assert.IsTrue( product.IsProperlyInitializedInstance( hint:"James" ) );
For test code you could use a reflection based equality, something like: Comparing object properties in c#
Many testing libraries provide such a utility, this way you don't have to change the design of your production code to suit the tests.

should i use extension method or member method in this case?

for example,
class Aclass
{
void method1()
{
int[] a = new int[5]{1,2,3,4,5};
var b = a.Accumulated().ToArray(); // so that b = {1,3,6,10,15}
}
}
Currently Accumulated() is an extension method. However an equivalent approach I reckon is to define a private member method in Aclass so that MakeAccumulated(a).ToArray() gives {1,3,6,10,15}.
What is a good practice?
Aclass is a place for methods which make logical sense for Aclass objects; best practice is to not use it as a general store for helper functions. A good rule of thumb is that if a method never references member variables then it might be out of place in the class.
A function on int arrays probably has no place in Aclass. I'd put it in an extension method.
it's not a question of good practice but of preference. both are valid options. if you need the method only in instances of Aclass then I'd limit it to a class method, that's also more obvious to others inspecting the class.
I would choose the member function approach, cause extensions methods, I personally, choose for something I'm not able to extend, or have a problem to extend to (complexity, not mine code, serialization issues, whatever...). In your case, you have a class written by you, so just extend it, by following clear OOP design.
For extension methods, you need to define another class, for someone who is not very familiar with your code, or for you after 2 years, will be not very clear why it's done in that way.
Regards.
If .Accumulated() is only going to be called from instances of Aclass, make it a member of the class. It wouldn't be practical to have an application-wide extension method for int[] (or Ienumerable as someone else pointed out) if it's only used within an instance of one class. Keep in mind that extension methods are just for added extensibility.
public static string Hello(this string Value) { return Value + "Hello"; }
string s = "Hello".Hello();
...is the same as:
public static string Hello(string Value) { return Value + "Hello"; }
string s = Utilities.Hello("Hello");
Would you put .Hello() in a utility class if you're only going to use it within the instance of another class? If you use .Accumulated() elsewhere in the application, though, an extension method would work.

Unit testing and checking private variable value

I am writing unit tests with C#, NUnit and Rhino Mocks.
Here are the relevant parts of a class I am testing:
public class ClassToBeTested
{
private IList<object> insertItems = new List<object>();
public bool OnSave(object entity, object id)
{
var auditable = entity as IAuditable;
if (auditable != null) insertItems.Add(entity);
return false;
}
}
I want to test the values in insertItems after a call to OnSave:
[Test]
public void OnSave_Adds_Object_To_InsertItems_Array()
{
Setup();
myClassToBeTested.OnSave(auditableObject, null);
// Check auditableObject has been added to insertItems array
}
What is the best practice for this? I have considered adding insertItems as a Property with a public get, or injecting a List into ClassToBeTested, but not sure I should be modifying the code for purposes of testing.
I have read many posts on testing private methods and refactoring, but this is such a simple class I wondered what is the best option.
The quick answer is that you should never, ever access non-public members from your unit tests. It totally defies the purpose of having a test suite, since it locks you into internal implementation details that you may not want to keep that way.
The longer answer relates to what to do then? In this case, it is important to understand why the implementation is as it is (this is why TDD is so powerful, because we use the tests to specify the expected behavior, but I get the feeling that you are not using TDD).
In your case, the first question that comes to mind is: "Why are the IAuditable objects added to the internal list?" or, put differently, "What is the expected externally visible outcome of this implementation?" Depending on the answer to those questions, that's what you need to test.
If you add the IAuditable objects to your internal list because you later want to write them to an audit log (just a wild guess), then invoke the method that writes the log and verify that the expected data was written.
If you add the IAuditable object to your internal list because you want to amass evidence against some kind of later Constraint, then try to test that.
If you added the code for no measurable reason, then delete it again :)
The important part is that it is very beneficial to test behavior instead of implementation. It is also a more robust and maintainable form of testing.
Don't be afraid to modify your System Under Test (SUT) to be more testable. As long as your additions make sense in your domain and follow object-oriented best practices, there are no problems - you would just be following the Open/Closed Principle.
You shouldn't be checking the list where the item was added. If you do that, you'll be writing a unit test for the Add method on the list, and not a test for your code. Just check the return value of OnSave; that's really all you want to test.
If you're really concerned about the Add, mock it out of the equation.
Edit:
#TonE: After reading your comments I'd say you may want to change your current OnSave method to let you know about failures. You may choose to throw an exception if the cast fails, etc. You could then write a unit test that expects and exception, and one that doesn't.
I would say the "best practice" is to test something of significance with the object that is different now that it stored the entity in the list.
In other words, what behavior is different about the class now that it stored it, and test for that behavior. The storage is an implementation detail.
That being said, it isn't always possible to do that.
You can use reflection if you must.
If I'm not mistaken, what you really want to test is that it only adds items to the list when they can be cast to IAuditable. So, you might write a few tests with method names like:
NotIAuditableIsNotSaved
IAuditableInstanceIsSaved
IAuditableSubclassInstanceIsSaved
... and so forth.
The problem is that, as you note, given the code in your question, you can only do this by indirection - only by checking the private insertItems IList<object> member (by reflection or by adding a property for the sole purpose of testing) or injecting the list into the class:
public class ClassToBeTested
{
private IList _InsertItems = null;
public ClassToBeTested(IList insertItems) {
_InsertItems = insertItems;
}
}
Then, it's simple to test:
[Test]
public void OnSave_Adds_Object_To_InsertItems_Array()
{
Setup();
List<object> testList = new List<object>();
myClassToBeTested = new MyClassToBeTested(testList);
// ... create audiableObject here, etc.
myClassToBeTested.OnSave(auditableObject, null);
// Check auditableObject has been added to testList
}
Injection is the most forward looking and unobtrusive solution unless you have some reason to think the list would be a valuable part of your public interface (in which case adding a property might be superior - and of course property injection is perfectly legit too). You could even retain a no-argument constructor that provides a default implementation (new List()).
It is indeed a good practice; It might strike you as a bit overengineered, given that it's a simple class, but the testability alone is worth it. Then on top of that, if you find another place you want to use the class, that will be icing on the cake, since you won't be limited to using an IList (not that it would take much effort to make the change later).
If the list is an internal implementation detail (and it seems to be), then you shouldn't test it.
A good question is, what is the behavior that would be expected if the item was added to the list? This may require another method to trigger it.
public void TestMyClass()
{
MyClass c = new MyClass();
MyOtherClass other = new MyOtherClass();
c.Save(other);
var result = c.Retrieve();
Assert.IsTrue(result.Contains(other));
}
In this case, i'm asserting that the correct, externally visible behavior, is that after saving the object, it will be included in the retrieved collection.
If the result is that, in the future, the passed-in object should have a call made to it in certain circumstances, then you might have something like this (please forgive pseudo-API):
public void TestMyClass()
{
MyClass c = new MyClass();
IThing other = GetMock();
c.Save(other);
c.DoSomething();
other.AssertWasCalled(o => o.SomeMethod());
}
In both cases, you're testing the externally visible behavior of the class, not the internal implementation.
The number of tests you need is dependent on the complexity of the code - how many decision points are there, roughly. Different algorithms can achieve the same result with different complexity in their implementation. How do you write a test that is independent of the implementation and still be sure you have adequate coverage of your decision points?
Now, if you are designing larger tests, at say the integration level, then, no, you would not want to write to implementation or test private methods, but the question was directed to the small, unit test scope.

What Advantages of Extension Methods have you found? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
A "non-believer" of C# was asking me what the purpose to extension methods was. I explained that you could then add new methods to objects that were already defined, especially when you don't own/control the source to the original object.
He brought up "Why not just add a method to your own class?" We've been going round and round (in a good way). My general response is that it is another tool in the toolbelt, and his response is it is a useless waste of a tool... but I thought I'd get a more "enlightened" answer.
What are some scenarios that you've used extension methods that you couldn't have (or shouldn't have) used a method added on to your own class?
The only advantage of extension methods is code readability. That's it.
Extension methods allow you to do this:
foo.bar();
instead of this:
Util.bar(foo);
Now there are a lot of things in C# that are like this. In other words there are many features in C# that seem trivial and don't have great benefit in and of themselves. However once you begin combining these features together you begin to see something just a bit bigger than the sum of its parts. LINQ benefits greatly from extension methods as LINQ queries would be almost unreadable without them. LINQ would be possible without extension methods, but not practical.
Extension methods are a lot like C#'s partial classes. By themselves they are not very helpful and seem trivial. But when you start working with a class that needs generated code, partial classes start to make a lot more sense.
I think extension methods help a lot when writing code, if you add extension methods to basic types you'll get them quicky in the intellisense.
I have a format provider to format a file size. To use it I need to write:
Console.WriteLine(String.Format(new FileSizeFormatProvider(), "{0:fs}", fileSize));
Creating an extension method I can write:
Console.WriteLine(fileSize.ToFileSize());
Cleaner and simpler.
Don't forget tooling! When you add an extension method M on type Foo, you get 'M' in Foo's intellisense list (assuming the extension class is in-scope). This make 'M' much easier to find than MyClass.M(Foo,...).
At the end of the day, it's just syntactic sugar for elsewhere-static-methods, but like buying a house: 'location, location, location!' If it hangs on the type, people will find it!
Two more benefits of extension methods that i have come across:
A fluent interface can be encapsulated in a static class of extension methods, thereby achieving a separation of concerns between the core class and it's fluent extensions; I've seen that achieve greater maintainability.
Extension methods can be hung off of interfaces, thereby allowing you to specify a contract (via an interface) and an associated series of interface-based behaviors (via extension methods), again offering a separation of concerns. An example are the Linq extension methods like Select(...), Where(...), etc. Hung off the IEnumerable<T> interface.
Some of the best uses I had for extension methods is the ability to:
Extend functionality on third party objects (whether commercial or internal to my company but managed by a separate group), which in many cases will be marked as sealed.
Create default functionality for interfaces without having to implement an abstract class
Take for example, IEnumerable<T>. While it is rich in extension methods, I found it annoying that it did not implement a generic ForEach method. So, I made my own:
public void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
{
foreach ( var o in enumerable )
{
action(o);
}
}
Voila, all my IEnumerable<T> objects regardless of implementing type, and whether or not I wrote it or someone else did now have a ForEach method by adding an appropriate "using" statement in my code.
One of the great reasons for using extension methods is LINQ. Without extension methods a lot of what you can do in LINQ would be very hard. The Where(), Contains(), Select extension methods means a lot more functionality is added to existing types without changing their structure.
There are plenty of answers about the advantages of extensions methods; how about one addressing the disadvantages?
The biggest disadvantage is that there's no compiler error or warning if you have a regular method and an extension method with the same signature in the same context.
Suppose you create an extension method applying to a particular class. Then later someone creates a method with an identical signature on that class itself.
Your code will compile, and you may not even get a runtime error. But you're no longer running the same code as before.
Fluent Interfaces and Context Sensitivity as demonstrated by Greg Young on CodeBetter
I would like to support the other answers here that mention improved code readability as an important reason behind extension methods. I'll demonstrate this with two aspects of this: method chaining vs. nested method calls, and cluttering of a LINQ query with meaningless static class names.
Let's take this LINQ query as an example:
numbers.Where(x => x > 0).Select(x => -x)
Both Where and Select are extension methods, defined in the static class Enumerable. Thus, if extension methods didn't exist, and these were normal static methods, the last line of code would essentially have to look like this:
Enumerable.Select(Enumerable.Where(numbers, x => x > 0), x => -x)
See how much nastier that query just got.
Second, if you now wanted to introduce your own query operator, you would naturally have no way of defining it inside the Enumerable static class, like all the other standard query operators, because Enumerable is in the framework and you have no control over that class. Therefore, you'd have to define your own static class containing extension methods. You might then get queries such as this one:
Enumerable.Select(MyEnumerableExtensions.RemoveNegativeNumbers(numbers), x => -x)
// ^^^^^^^^^^^^^^^^^^^^^^
// different class name that has zero informational value
// and, as with 'Enumerable.xxxxxx', only obstructs the
// query's actual meaning.
My personal argument for Extension methods is, they fit very well into an OOP design:
consider the simple method
bool empty = String.IsNullOrEmpty (myString)
in comparison to
bool empty = myString.IsNullOrEmpty ();
There are heaps of great answers above about what extension methods let you do.
My short answer is - they nearly eliminate the need for factories.
I'll just point out that they are not a new concept and one of the biggest validations of them is that they are a killer feature in Objective-C (categories). They add so much flexibility to framework-based development that NeXT had NSA and Wall Street financial modelers as major users.
REALbasic also implements them as extends methods and they have been of similar use there simplifying development.
Its true that you can add your (extension) method directly into your class. But not all classes are written by you. Classes from the core library or third party libraries are often closed and it would be impossible to get the syntatic sugar without extension methods. But remember, extension methods are just like (static) standalone methods in eg. c++
Extension methods can also help keep your classes and class dependencies clean. For instance, you may need a Bar() method for the Foo class everywhere Foo is used. However, you may want a .ToXml() method in another assembly and only for that assembly. In that case, you can add the necessary System.Xml and/or System.Xml.Linq dependencies in that assembly and not in the original assembly.
Benefits: dependencies in your defining class assembly is reduced to only the bare necessities and other consuming assemblies will be prevented from using the ToXml() method. See this PDC presentation for further reference.
I agree that extension methods increases readability of code, but it's really nothing else than static helper methods.
IMO using extension methods for adding behaviour to your classes can be:
Confusing:
Programmers might believe that methods are a part of the extended type, thus not understanding why the methods are gone when the extension-namespace isn't imported.
An antipattern:
You decide to add behaviour to types in your framework using extension methods, then shipping them off to some person which into unit testing. Now he's stuck with a framework containing a bunch of methods he can't fake.
Extension methods are really the .NET incorporation of the "Introduce Foreign Method"refactor from Martin Fowler's Book (down to the method signature). They come with basically the same benefits and pitfalls. In the section on this refactor he says that they're a work-around for when you can't modify the class that should really own the method.
I mainly see extension methods as an admission that perhaps they shouldn't have disallowed free functions.
In the C++ community, it is often considered good OOP practice to prefer free nonmember functions over members, because these functions don't break encapsulation by gaining access to private members they don't need. Extension methods seem to be a roundabout way to achieve the same thing. That is, a cleaner syntax for static functions which don't have access to private members.
Extension methods are nothing more than syntactic sugar, but I don't see any harm in using them.
Intellisense on the object itself instead of having to call some ugly utility function
For conversion functions, can change "XToY(X x)" to "ToY(this X x)" which results in pretty x.ToY() instead of ugly XToY(x).
Extend classes you have no control over
Extend functionality of classes when its undesirable to add methods to the classes themselves. For example, you can keep business objects simple and logic-free, and add specific business logic with ugly dependencies in extension methods
I use them to reuse my object model classes. I have a bunch of classes that represent objects that I have in a database. These classes are used in the client side only to display the objects so the basic usage is accessing properties.
public class Stock {
public Code { get; private set; }
public Name { get; private set; }
}
Because of that usage pattern I don't want to have business logic methods in these classes, so I make every business logic to be an extension method.
public static class StockExtender {
public static List <Quote> GetQuotesByDate(this Stock s, DateTime date)
{...}
}
This way I can use the same classes for business logic processing and for user interface displaying without overloading the client side with unnecessary code.
One interesting thing about this solution it's that my object model classes are dynamic generated using Mono.Cecil, so it would be very difficult to add business logic methods even if I wanted. I have a compiler that reads XML definition files and generate these stubs classes representing some object I have in the database. The only approach in this case is to extend them.
It allows C# to better support dynamic languages, LINQ and a dozen other things. Check out Scott Guthrie's article.
In my last project, I used extension method to attach Validate() methods to business objects. I justified this because the business objects where serializable data transfer objects and will be used in diffrent domains as they where general ecommerce entities such as product, customer, merchant etc. Well in diffrent domains the business rules may be diffrent as well so I encapsulated my late bound validation logic in a Validate method attahced to the base class of my data transfer objects. Hope this makes sense :)
One case where extension methods were quite useful was in a client-application that uses ASMX web services. Due to the serialization, the return types of web methods do not contain any methods (only the public properties of these types are available on the client).
Extension methods allowed use to add functionality (on the client-side) to the types returned by web methods without having to create yet another object model or numerous wrapper classes on the client-side.
Extension methods can be used to create a kind of mixin in C#.
This, in turn, provides better separation of concerns for orthogonal concepts. Take a look at this answer as an example.
This can also be used to enable roles in C#, a concept central to the DCI architecture.
Also remember that extension methods were added as a way to help Linq query to be more readable, when used in their C# style.
These 2 affectations are absolutely equivalent, yet the first is far more readable (and the gap in readibility would of course increase with more methods chained).
int n1 = new List<int> {1,2,3}.Where(i => i % 2 != 0).Last();
int n2 = Enumerable.Last(Enumerable.Where(new List<int> {1,2,3}, i => i % 2 != 0));
Note that the fully qualified syntax should even be :
int n1 = new List<int> {1,2,3}.Where<int>(i => i % 2 != 0).Last<int>();
int n2 = Enumerable.Last<int>(Enumerable.Where<int>(new List<int> {1,2,3}, i => i % 2 != 0));
By chance, the type parameters of Where and Last don't need to be explicitely mentioned as they can be infered thanks to the presence of the first parameter of these two methods (the parameter which is introduced by the keyword this and make them extension methods).
This point is obviously an advantage (among others) of the extension methods, and you can take benefit from it in every similar scenario where method chaining is involved.
Especially, it is the more elegant and convincing way I found to have a base class method invokable by any subclass and returning a strongly typed reference to this subclass (with the subclass type).
Example (ok, this scenario is totally cheesy) : after a good night, an animal opens the eyes then gives a cry; every animal opens the eyes the same way, whereas a dog barks and a duck kwaks.
public abstract class Animal
{
//some code common to all animals
}
public static class AnimalExtension
{
public static TAnimal OpenTheEyes<TAnimal>(this TAnimal animal) where TAnimal : Animal
{
//Some code to flutter one's eyelashes and then open wide
return animal; //returning a self reference to allow method chaining
}
}
public class Dog : Animal
{
public void Bark() { /* ... */ }
}
public class Duck : Animal
{
public void Kwak() { /* ... */ }
}
class Program
{
static void Main(string[] args)
{
Dog Goofy = new Dog();
Duck Donald = new Duck();
Goofy.OpenTheEyes().Bark(); //*1
Donald.OpenTheEyes().Kwak(); //*2
}
}
Conceptually OpenTheEyes should be an Animal method, but it would then return an instance of the abstract class Animal, which doesn't know specific subclass methods like Bark or Duck or whatever. The 2 lines commented as *1 and *2 would then raise a compile error.
But thanks to the extension methods, we can have kind of a "base method which knows the subclass type on which it is called".
Note that a simple generic method could have done the job, but in a far more awkward way :
public abstract class Animal
{
//some code common to all animals
public TAnimal OpenTheEyes<TAnimal>() where TAnimal : Animal
{
//Some code to flutter one's eyelashes and then open wide
return (TAnimal)this; //returning a self reference to allow method chaining
}
}
This time, no parameter and thus no possible return type inference. The call can be nothing other than :
Goofy.OpenTheEyes<Dog>().Bark();
Donald.OpenTheEyes<Duck>().Kwak();
... which can weigh the code a lot if more chaining is involved (especially knowing that the type parameter will always be <Dog> on Goofy's line and <Duck> on Donald's one...)
I have only one word to tell about it: MAINTAINABILITY this is the key for extension methods use
I think extension methods help to write code that is clearer.
Instead of putting a new method inside your class, as your friend suggested, you put it in the ExtensionMethods namespace. In this way you maintain a logical sense of order to your class. Methods that don't really directly deal with your class won't be cluttering it up.
I feel extension methods make your code clearer and more appropriately organized.
It allows your editor/IDE do auto-complete suggestion smart.
I love them for building html.
Frequently there are sections that are used repeatedly, or generated recursively where a function is useful but would otherwise break the flow of the program.
HTML_Out.Append("<ul>");
foreach (var i in items)
if (i.Description != "")
{
HTML_Out.Append("<li>")
.AppendAnchor(new string[]{ urlRoot, i.Description_Norm }, i.Description)
.Append("<div>")
.AppendImage(iconDir, i.Icon, i.Description)
.Append(i.Categories.ToHTML(i.Description_Norm, urlRoot)).Append("</div></li>");
}
return HTML_Out.Append("</ul>").ToString();
There are also situations where an object needs custom logic to be prepared for HTML output- extension methods let you add this functionality without mixing presentation and logic within the class.
I've found extension methods are useful to match nested generic arguments.
That sounds a bit wierd - but say we have a generic class MyGenericClass<TList>, and we know that TList itself is generic (e.g. a List<T>), I don't think that there's a way to dig out that nested 'T' from the List without either extension methods or static helper methods. If we only have static helper methods at our disposal, it's (a) ugly, and (b) will force us to move functionality that belongs in the class to an external location.
e.g. to retrieve the types in a tuple and convert them into a method signature we can use extension methods:
public class Tuple { }
public class Tuple<T0> : Tuple { }
public class Tuple<T0, T1> : Tuple<T0> { }
public class Caller<TTuple> where TTuple : Tuple { /* ... */ }
public static class CallerExtensions
{
public static void Call<T0>(this Caller<Tuple<T0>> caller, T0 p0) { /* ... */ }
public static void Call<T0, T1>(this Caller<Tuple<T0, T1>> caller, T0 p0, T1 p1) { /* ... */ }
}
new Caller<Tuple<int>>().Call(10);
new Caller<Tuple<string, int>>().Call("Hello", 10);
That said, I'm not sure where the dividing line should be - when should a method be an extension method, and when should it be a static helper method? Any thoughts?
I have input zones on my screen, and all must implement a standard behavior whatever their exact types are (textboxes, checkboxes, etc.). They cannot inherit a common base class as each type of input zone already derives from a specific class (TextInputBox, etc.)
Maybe by going up in the inheritance hierachy I could find a common ancestor like say WebControl, but I didn't develop the framework class WebControl and it doesn't expose what I need.
With the extension method, I can :
1) extend the WebControl class, and then obtain my unified standard behavior on all my input classes
2) alternatively make all my classes derive from an interface, say IInputZone, and extend this interface with methods. I will now be able to call extensions methods related to the interface on all my input zones. I thus achieved a kind of multiple inheritance since my input zones already derived from multiple base classes.
There are so many great examples of extension methods..especially on IEnumerables as posted above.
e.g. if I have an IEnumerable<myObject> I can create and extension method for IEnumerable<myObject>
mylist List<myObject>;
...create the list
mylist.DisplayInMyWay();
Without Extension Methods would have to call:
myDisplayMethod(myOldArray); // can create more nexted brackets.
another great example is creating a Circular Linked List in a flash!
I can' take credit for it!
circlular linked list using extension Methods
Now combine these and using extension Methods code reads as follows.
myNode.NextOrFirst().DisplayInMyWay();
rather than
DisplayInMyWay(NextOrFirst(myNode)).
using Extension Methods It is neater and easier to read and more object orientated.
also very close to :
myNode.Next.DoSomething()
Show that to your collegue! :)

Categories