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.
Related
I have a good complete class which is doing awesome things. I need to allow users to use this class by replacing some methods in it, but inheritance is not allowed, because this class also used in other application classes.
It is like you have a class which creating a table, but you need to allow users to redefine method which is creating table cell to let the user print something custom in this cell. The class, however, has a default way to print the cell content (in case the user do not need to customize it).
Is there any common-used or standartized way to achieve this?
Updated
Having had "the peanut gallery" point out that my approach (at bottom) wouldn't fit the bill, here's another way:
Use delegation. Define certain public properties with type Action or Func. Where these behaviors need to be invoked in your code, compare the properties to null. If null, use your default behavior. If not, invoke the values.
Your calling code MAY set the properties, but doesn't have to.
(first try) Alternative approaches:
You are describing an extension method, or the use of inheritance if that's available.
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. For client code written in C# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type.
https://msdn.microsoft.com/en-us//library/bb383977.aspx
Inheritance, together with encapsulation and polymorphism, is one of the three primary characteristics (or pillars) of object-oriented programming. Inheritance enables you to create new classes that reuse, extend, and modify the behavior that is defined in other classes. The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. A derived class can have only one direct base class. However, inheritance is transitive. If ClassC is derived from ClassB, and ClassB is derived from ClassA, ClassC inherits the members declared in ClassB and ClassA.
https://msdn.microsoft.com/en-us/library/ms173149.aspx
You can't derive from all .NET types, but you can write extension methods for them.
Assuming you are able to modify the existing class, you should be marking your method as virtual.
This will allow you to provide a default implementation (which is what your existing code will use) and be able to override it with a custom one where needed.
Your base class could be something along the lines of:
public class TableMaker
{
public virtual string MakeTable()
{
//Provide default implementation used by existing code here
}
}
Your inheriting class can then override the virtual method:
public class SpecialTableMaker : TableMaker
{
public override string MakeTable()
{
//Provide specific implementation for cell text here
}
}
You existing code will work just fine and you can use this other class where you need it.
I've finally ended with this solution. It was proposed by #codenoir, however I also have a code which demonstrates a whole mechanism.
public class MyTable
{
public delegate string OnInsertHandler();
public event OnInsertHandler OnInsert;
public string Show()
{
string res = "-BEGIN-";
if (OnInsert != null) {
res += OnInsert ();
} else {
res += "#default insert#";
}
res += "-END-";
return res;
}
}
public class DelegateTester
{
public void OnTest()
{
MyTable mt = new MyTable();
Debug.Log("Default output: " + mt.Show()); // Shows "-BEGIN-#default insert#-END-"
// Changing functionality via delegate
mt.OnInsert += MyCustomInsert;
Debug.Log("Customized output: " + mt.Show()); // Shows "-BEGIN-#custom insert#-END-"
// Remove delegate
mt.OnInsert -= MyCustomInsert;
Debug.Log("Rollbacked output: " + mt.Show()); // Shows "-BEGIN-#default insert#-END-"
}
public string MyCustomInsert()
{
return "#custom insert#";
}
}
In this example I am using MyTable class which is extended using Func delegate. This way I can allow to users of my software module to extend only one method without make any mess with others classes and objects.
I just updated Visual Studio 2013 and I noticed that in the project template for an MVC application the ApplicationDbContext class now has a static method that just calls the constructor:
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
This seems like clutter to me but I imagine that there is some semantic reason that I should now start using ApplicationDbContext.Create() instead of new ApplicationDbContext(). Are there any benefits to doing so?
Actually. yes.
In your specific case, wrapping it thusly allows you to quickly start bolting on logic, such as making the ApplicationDbContext and singleton or handling an exception in a common way for the whole application. Since a constructor cannot return null, this can be very important to be able to catch an exception and return null.
Tuple.Create is the prime example of generic inference, which does not work with Constructors. This allows you say
Tuple.Create(Item1, Item2.. ItemN);
And the let the compiler infer types, rather than
new Tuple<T1, T2...Tn>(Item1, Item2...ItemN);
Which is more verbose, and takes a bit more work if you want to switch out one of those types.
There is also the case of Anonymous types, which cannot be specified explicitly and thus cannot be used in new statements. I have specifically had occasion where, while searching assemblies for a specific Attribute to link a command structure for, I wanted to make an enumerable (a Queue, in this case) out of an anonymous type during the search to pair class references with their constructor and string arguments, rather than looking these up every time they're needed. Since I can again use Generic inference in a method, I was able to wrap the constructor in an extension method and get the job done.
There are also cases for singleton patterns, wherein you want the "GetInstance" method to usually create a value, or get one if it exists. May not qualify since it does slightly more than wrap a constructor.
In addition, there are plenty of cases where you may want to control implementation procedures, such as forcing them onto other threads, logging them in a database to be undone later, or bolting on a permissions system, all of which can be done by making a constructor wrapper and adding a few more lines of logic, and then privatizing the constructor to avoid it being called directly.
There are also cases where I've created a factory method which delegates to known children in order to provide a different implementation of a returned interface or abstract based on provided parameters. This has the added benefit of being able to hide the implementing classes - the Type class and IEnumerable interface make use of this pattern.
This pattern can be very useful, especially if you use a private constructor, and return an interface type from the Create, rather than the concrete type.
private ApplicationDbContext()
{
}
public static IApplicationDbContext Create()
{
return new ApplicationDbContext();
}
Now consumers of your class are prevented from depending on the concrete implementation - they can only rely on the abstraction.
Wrapping the constructor with static methods (creation methods) allows you to chose a specific name that conveys information. You can also create several methods with the same parameter signature such as CreateX(float f) and CreateY(float f), which you cannot do with constructors.
A situation where this is really useful is e.g. for creating structs that represent physical quantities that may have several units, such as time, length or weight. Here, you could use creation methods to force the programmer to always explicitly specify the unit instead of just passing a unit-less number to a single constructor (which assumes a certain unit, and getting it wrong might have huge consequences).
Example:
public struct Length
{
private const double MetersPerYard = 0.9144;
private double _meters;
private Length(double meters)
{
_meters = meters;
}
public static Length FromMeters(double meters)
{
return new Length(meters);
}
public static Length FromYards(double yards)
{
return new Length(yards*MetersPerYard);
}
public double Meters
{
get { return _meters; }
}
public double Yards
{
get { return _meters / MetersPerYard; }
}
}
Or take a look at TimeSpan and methods like FromMinutes, FromSeconds etc.
Sorry if the question sounds confusing. What I mean is that if I have a class that has a method that does a bunch of calculations and then returns a value, I can either make that method public (which gives my other classes access), or I can make it private and make a public get method.
Something like this:
public publicmethod{
return privatemethod();
}
private privatemethod{
//do stuff
return value;
}
Is this a futile exercise or does it provide additional program security?
Well, there is no additional security here. However, such a usage can sometimes make sense.
For example, the private and public method may have different semantics.
// base class
public virtual BuyFood()
{
BuyPizza();
BuyCoke();
}
private void BuyPizza()
{
// ...
}
// derived class
public override void BuyFood()
{
BuyChopSuey();
}
private void BuyChopSuey()
{
// ...
}
So your implementation is just calling to a private method -- but what is important, you expose the semantics: your BuyFood operation is just BuyChopSuey(). Your code says: "in this class, buying food is just buying chop suey" in a clear way. You are able to add BuyTsingtaoBeer() into BuyFood() any time without changing the semantics of the both methods.
It is completely redundant. It does not provide anything except another name for the same thing and another indirection for readers to follow. Simply make a single implementation, and make it public. On the same note, getX() { return x; } setX(T newX) { x = newX; } does not encapsulate anything, at best it's future-proofing.
You may end up implementing a particular function required by an interface in a single line, largely delegating to (possibly private) methods which exist for other good reasons. This is different, and more justified (but again, if it's only return someMethod(); you should probably abolish the private implementation and assume the common name). A particular case if when you need two implement two methods which do the same thing (e.g. from separate interfaces).
I think either way is fine, it's more a matter of style assuming the method doesn't change the state of the class. If you have a class that has a bunch of properties and very few methods, it probably makes more sense to define another property. If you have a lot of methods in the class but few properties, then a method is more consistent with your overall class design.
If the method changes a bunch of other class variables than I'd expose it as a public method instead of a property.
I don't think either way, property or method, is necessarily more secure. It depends on what checks you do - is the caller allowed to perform the calculation? Are all variables used in the calculations within acceptable ranges? Etc. All of these checks can be performed whether you are using a property or a method.
Well, actually the question is What code do I want to be able to call this method?
Any code in general, even from other assemblies? Make the method public.
Any code from the same assembly? Make it internal.
Only code from this class? Make it private.
Having a private method directly aliased to a public method only makes the private method callable from the outside, which contradicts its private status.
If the method only does some calculation and doesn't use or change anything in the object, make it a public static method:
public static CalculationMethod(int input) {
//do stuff
return value;
}
That way any code can use the method without having the create an instance of the class:
int result = ClassName.CalculationMethod(42);
Instead of public consider internal, which would give access only to code in the same assembly.
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.
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.