Let's say I have an interface, like this:
public interface ILoggable
{
void Log(Func<string> message, Logger.Type type);
}
And some extension methods, like this:
public static class Logger
{
public static void Log(this ILoggable loggable, Func<string> message) { loggable.Log(message, Type.Information); }
public static void Log(this ILoggable loggable, string prefix, byte[] data, int len) { /* snip */ }
public static void Log(this ILoggable loggable, Exception ex) { /* snip */ }
// And so on...
}
Then in any class CoreService : ServiceBase, ILoggable or such I implement that public void Log(Func<string> message, Logger.Type type) to whatever I like (public modifier being kind of meh...) and use all the extension methods to do actual logging.
So far so good... or not so good? Is there something wrong with this approach? If not, then why the inconvenience:
catch (Exception ex) {
this.Log(ex); // this works
Log(ex); // this goes not
It seems like a reasonable approach to me in itself1 - but the requirement to explicitly state this is just part of how the language works around extension methods. I suspect this makes aspects of the language specification cleaner, and this requirement is sufficiently rare (and the workaround sufficiently easy) that it was felt to be better to go with the current solution than to make things more complicated just to avoid five characters in a relatively rare scenario.
Member lookup for simple names (section 7.6.2 of the C# 4 spec) is complicated enough without making it worse. Don't forget that the simple name can refer to a type or a type parameter, as well as a method. There's a lot going on there already.
When I get to work I'll check if there are any annotations around section 7.6.5.2 (extension method invocation) which give "inside information" about this.
1 On reflection, it does seem slightly odd for the entity doing the logging to also want to log other things - the only kind of exception I'd expect it to see would be when the logging is failing, in which case logging the exception would fail too.
Related
I am doing a refactor over certain code.
We have a list of investors with amounts assigned to each. The total of amounts should be equal to another total, but sometimes there are a couple of cents of difference, so we use different algorithms to assign these differences to each investor.
The current code is something like this:
public void Round(IList<Investors> investors, Enum algorithm, [here goes a list of many parameters]) {
// some checks and logic here - OMMITED FOR BREVITY
// pick method given algorithm Enum
if (algoritm == Enum.Algorithm1) {
SomeStaticClass.Algorithm1(investors, remainders, someParameter1, someParameter2, someParameter3, someParameter4)
} else if (algoritm == Enum.Algorithm2) {
SomeStaticClass.Algorithm2(investors, remainders, someParameter3)
}
}
so far we only have two algorithms. I have to implement the third one. I was given the possibility to refactor both existing implementations as well as do some generic code to make this function for future algorithms, maybe custom to each client.
My first thought was "ok, this is a strategy pattern". But the problem I see is that both algorithms receive a different parameter list (except for the first two). And future algorithms can receive a different list of parameters as well. The only thing in "common" is the investor list and the remainders.
How can I design this so I have a cleaner interface?
I thought of
Establishing an interface with ALL possible parameters, and share it
among all implementations.
Using an object with all possible parameters as properties, and use that generic object as part of the interface. I
would have 3 parameters: The list of investors, the remainders object, and a "parameters" object. But in this case, I have a similar problem. To instantiate each object and fill the required properties depends on the algorithm (unless I set all of them). I
would have to use a factory (or something) to instantiate it, using all parameters in the interface, am I right? I would be moving the problem of too many parameters to that "factory" or whatever.
Using a dynamic object instead of a statically typed object. Still
presents the same problems as before, the instantiation
I also thought of using the Visitor Pattern, but as I understand, that would be the case if I had different algorithms for different entities to use, like, another class of investors. So I don't think it is the right approach.
So far the one that convinces me the most is the second, although I am still a bit reticent about it.
Any ideas?
Thanks
Strategy has different implementations. Its straightforward when all alternate Concrete Strategies require same type signature. But when concrete implementations start asking for different data from Context, we have to gracefully take a step back by relaxing encapsulation ("breaking encapsulation" is known drawback of strategy), either we can pass Context to strategies in method signature or constructor depending upon how much is needed.
By using interfaces and breaking big object trees in to smaller containments we can restrict the access to most of the Context state.
following code demonstrates passing through method parameter.
public class Context {
private String name;
private int id;
private double salary;
Strategy strategy;
void contextInterface(){
strategy.algorithmInterface(this);
}
public String getName() {
return name;
}
public int getId() {
return id;
}
public double getSalary() {
return salary;
}
}
public interface Strategy {
// WE CAN NOT DECIDE COMMON SIGNATURE HERE
// AS ALL IMPLEMENTATIONS REQUIRE DIFF PARAMS
void algorithmInterface(Context context);
}
public class StrategyA implements Strategy{
#Override
public void algorithmInterface(Context context) {
// OBSERVE HERE BREAKING OF ENCAPSULATION
// BY OPERATING ON SOMEBODY ELSE'S DATA
context.getName();
context.getId();
}
}
public class StrategyB implements Strategy{
#Override
public void algorithmInterface(Context context) {
// OBSERVE HERE BREAKING OF ENCAPSULATION
// BY OPERATING ON SOMEBODY ELSE'S DATA
context.getSalary();
context.getId();
}
}
Okay, I might be going in the wrong direction... but it seems kinda weird that you're passing in arguments to all the algorithms, and the identifier to which algorithm to actually use. Shouldn't the Round() function ideally just get what it needs to operate?
I'm imagining the function that invokes Round() to look something like:
if (something)
algToUse = Enum.Algorithm1;
else
if (otherthing)
algToUse = Enum.Algorithm2;
else
algToUse = Enum.Algorithm3;
Round(investors, remainder, algToUse, dayOfMonth, lunarCycle, numberOfGoblinsFound, etc);
... what if, instead, you did something like this:
public abstract class RoundingAlgorithm
{
public abstract void PerformRounding(IList<Investors> investors, int remainders);
}
public class RoundingRandomly : RoundingAlgorithm
{
private int someNum;
private DateTime anotherParam;
public RoundingRandomly(int someNum, DateTime anotherParam)
{
this.someNum = someNum;
this.anotherParam = anotherParam;
}
public override void PerformRounding(IList<Investors> investors, int remainder)
{
// ... code ...
}
}
// ... and other subclasses of RoundingAlgorithm
// ... later on:
public void Round(IList<Investors> investors, RoundingAlgorithm roundingMethodToUse)
{
// ...your other code (checks, etc)...
roundingMethodToUse.Round(investors, remainders);
}
... and then your earlier function simply looks like:
RoundingAlgorithm roundingMethod;
if (something)
roundingMethod = new RoundingByStreetNum(1, "asdf", DateTime.Now);
else
if (otherthing)
roundingMethod = new RoundingWithPrejudice(null);
else
roundingMethod = new RoundingDefault(1000);
Round(investors, roundingMethod);
... basically, instead of populating that Enum value, just create a RoundingAlgorithm object and pass that in to Round() instead.
I created a little abstract domain to illustrate the problem I am facing, so there it is.
There is a medieval game, where the players are generals of their army and the entire battle is mostly affected by the battle plan, which is made before the battle begins, in let's say preparation mode.
To achieve what's needed, I created an interface IBattleUnit and kept things pretty simple:
public interface IBattleUnit
{
void Move();
void Attack();
string Salute();
}
Having three types of units will do the job for now, so Archer.cs, Pikeman.cs and Swordsman.cs implement the interface in pretty much the same way:
public class Swordsman : IBattleUnit
{
private Swordsman() {}
public void Move()
{
//swordsman moves
}
public void Attack()
{
//swordsman attacks
}
public string Salute()
{
return "Swordsman at your service, master.";
}
}
Note the private constructor, it is intended for battle units to be recruited only in Barracks, this is the generic factory
public static class Barracks<T> where T : class, IBattleUnit
{
private static readonly Func<T> UnitTemplate = Expression.Lambda<Func<T>>(
Expression.New(typeof(T)), null).Compile();
public static T Recruit()
{
return UnitTemplate();
}
}
Note: precompiled lambda expressions for the empty constructor make (on my machine) unit creation faster, and whereas the army can get really big, fast generic creation is exactly what I want to achieve.
For having covered everything a battle needs to be started, the BattlePlan explanation is the only missing part, so here we come:
public static class BattlePlan
{
private static List<Type> _battleUnitTypes;
private static List<Type> _otherInterfaceImplementors;
//...
private static Dictionary<string, string> _battlePlanPreferences;
private static Type _preferedBattleUnit;
private static Type _preferedTransportationUnit;
//...
static BattlePlan()
{
//read the battle plan from file (or whereever the plan init data originate from)
//explore assemblies for interface implementors of all kinds
//and finally fill in all fields
_preferedBattleUnit = typeof (Archer);
}
public static Type PreferedBattleUnit
{
get
{
return _preferedBattleUnit;
}
}
//... and so on
}
Now if you have reached this, you are aware of the whole domain - it even compiles and everything looks bright, until...
Until now: I create a console application, add references to the above mentioned, and try to profit from what's under the hood.
For complete description of my confusion, I note what IS WORKING first:
If I want the Barracks to give me a specific BattleUnit, I can instantiate it and let it fight, move and salute. If the instantiation is done this way:
IBattleUnit unit = Barracks<Pikeman>.Recruit();
If I want to know what is the prefered unit based on battle plan, I can get it, I can ask for its AssemblyQualifiedName, I get the Type (in fact it is Archer, just as it stays in BattlePlan) , long story short, I get what I expect to, when I call:
Type preferedType = BattlePlan.PreferedBattleUnit;
And here, when I expect the BattlePlan to supply me with a Type and me just passing the Type to Barracks in order to instantiate some kind of Unit, VisualStudio2012 (resharper of current version) stops me and does not compile the code, while the code, that leads to the error is:
Type t = Type.GetType(BattlePlan.PreferedBattleUnit.AssemblyQualifiedName);
IBattleUnit u = Barracks<t>.Recruit();
No matter what I do, no matter whether I pass the t, or pass it as typeof(t), or try converting it to IRepository ... I still end up not being able to compile such code, with (at least) two errors in the error list:
Error 1 Cannot implicitly convert type 't' to 'BattleUnits.cs.IBattleUnit' Program.cs
Error 2 The type or namespace name 't' could not be found (are you missing a using directive or an assembly reference?) Program.cs
So to the actual questions:
Is there some way, I could pass the type to Barracks, not having to change underlying infrastructure?
Or is there anything I am doing wrong by design?
I have spent the last two days googling around and still, with the only clear way being changing the Barracks, which in fact is what I would not want to.
EDIT no.1: When re-thinking the concept and everything : IBattleUnit was first described as a set of core battle actions every Unit will be able to do (and we want it to be this way). I did not want to introduce base classes, just because I knew, there could possibly be GroundUnitBase and FlyingUnitBase abstract classes for the sake, we would like to have clear and logical design... But there absolutely has to be only one static Barracks.
Still for the BattleUnits - putting one base class in my eyes now seems could change the things for code being runnable and I'm right on my way of trying that out ... reading, what I wrote made me think about UnitBase class could possibly help not even the design but in some way its compilability. So this is the first idea in my mind after rethinking what's written.
You don't really need Barracks to be generic.
This solution doesn't use reflection so it's much more efficient:
public static class Barracks
{
private static readonly IDictionary<Type, Func<IBattleUnit>> FactoryMethods = new Dictionary<Type, Func<IBattleUnit>>();
public static void Register<T>(Func<IBattleUnit> factory) where T : IBattleUnit
{
FactoryMethods.Add(typeof(T), factory);
}
public static IBattleUnit Recruit<T>() where T : IBattleUnit
{
return Recruit(typeof (T));
}
public static IBattleUnit Recruit(Type type)
{
Func<IBattleUnit> createBattleUnit;
if (FactoryMethods.TryGetValue(type, out createBattleUnit))
{
return createBattleUnit();
}
throw new ArgumentException();
}
}
public class Swordsman : IBattleUnit
{
static Swordsman()
{
Barracks.Register<Swordsman>(() => new Swordsman());
}
}
public static class Barracks
{
public static IBattleUnit Recruit(Type preferredType)
{
return (IBattleUnit)typeof(Barracks<>).MakeGenericType(preferredType).GetMethod("Recruit", BindingFlags.Public|BindingFlags.Static).Invoke(null,null);
}
}
then call
Barracks.Recruit(BattlePlan.PreferredBattleUnit)
You can do this using reflection, something like this:
IBattleUnit unit = typeof(Barracks).GetMethod("Recruit").MakeGenericType(BattlePlan.PreferedBattleUnit).Invoke(null, null) as IBattleUnit;
If you have an instance of the PreferedBattleUnit you simply need to use the dynamic keyword. Please have a look at this question (John Skeet answer): (EDIT: This might not be very helpful as your method is not generic)
Pass concrete object type as parameter for generic method
If you don't have an instance of the object than have a look at the following question (again, John Skeet answer):
Generics in C#, using type of a variable as parameter
My strategy would be to create a Dictionary<Type, Barracks<IBattleUnit>>, assuming you intend to have all the barracks defined before you try to retrieve from them. That way you can match by the key and cast safely.
This would require the Barracks<> to not be a static class. Unless you have very specific reasons like some kind of external resource you're managing (and arguably even then), you probably have no need for a static class.
While it may seem like creating statics for all of these will make everything easier, ultimately you create a dependency on a resource that may change. If you invent another unit type, you have to register it with the barracks, which is in no real way different than the reason you don't want to make base classes, and if you forget you'll throw exceptions, which is even worse, because it violates the Principle of Least Surprise.
I am decoding comms messages from a binary stream. I create message objects of varying types depending on what messages have arrived. They all derive from a base CommsMessage type. All fine and dandy.
Elsewhere in my code I need to react to these messages, so I need to know what type of message it is.
Currently I am doing:
void ProcessIncomingMessage(CommsMessage msg)
{
if (msg is MessageType1)
return ProcessMessageType1(msg as MessageType1);
if (msg is MessageType2)
return ProcessMessageType2(msg as MessageType2);
//etc
}
I am wondering what the performance cost of comparing these types are, and whether I should include a MessageType property in the base class instead. Then I could do:
void ProcessIncomingMessage(CommsMessage msg)
{
switch (msg.MessageType)
{
case MessageType.Type1: return ProcessMessageType1(msg as MessageType1);
case MessageType.Type2: return ProcessMessageType2(msg as MessageType2);
//etc
}
}
Yes, this is premature optimisation, and I'm probably worrying over insignificant details, but I'm the kind of coder who likes to know what's going on under the covers and so was wondering the performance differences between the two. I guess I have a prejudice against type comparisons from my C++ background where RTTI introduced an overhead, and just wondered if .Net had any similarities.
Have you considered eliminating the type casts?
I'm guessing you've considered that putting the virtual method on the Message type itself would break a layering abstraction (e.g. you might want a clean separation of the processing of the message from the message itself). Maybe consider the visitor pattern. This'll allow you to separate out the Message class from the processing of the Message itself.
If you have something of this structure.
abstract class CommsMessage {}
class Message1 : CommsMessage {}
class Message2 : CommsMessage {}
You could refactor to
abstract class CommsMessage
{
public abstract void Visit(CommsMessageVisitor v);
}
class Message1 : CommsMessage
{
public void Visit(CommsMessageVisitor v) { v.Accept(this); }
}
class Message2 : CommsMessage
{
public void Visit(CommsMessageVisitor v) { v.Accept(this); }
}
interface CommsMessageVisitor
{
void Accept(Message1 msg1);
void Accept(Message1 msg2);
}
At this point, you've eliminated the type-casts. You can now rewrite your code as
void ProcessIncomingMessage(CommsMessage msg)
{
new MyVisitor().Visit(msg);
}
class MyVisitor : CommsMessageVisitor
{
void Accept(Message1 msg1) { ProcessMessageType1(msg1); }
void Accept(Message1 msg2) { ProcessMessageType2(msg2); }
}
Of course there might be reasons you can't do this, but it's always nicer to avoid type casts if you can!
Note that your code is not syntactically valid, as the return types are void, but anyway.
Well, I'm not too sure about the performance difference of the two alternatives you show. However, at least FxCop would "suggest" the following instead of your first solution:
void ProcessIncomingMessage(CommsMessage msg)
{
MessageType1 msg1 = msg as MessageType1;
if (msg1 != null)
{
ProcessMessageType1(msg1);
return;
}
MessageType2 msg2 = msg as MessageType2;
if (msg2 != null)
{
ProcessMessageType2(msg2);
return;
}
//etc
}
Of course, there are other issues involved here like maintainability, comprehensibility, etc.
Possibly it would be better to provide an "virtual void ProcessMessage()" on your "CommsMessage" class, that you overwrite for each "MessageType". Then let the CLR work for you.
public class CommsMessage
{
public virtual void ProcessMessage()
{
// Common stuff.
}
}
public class MessageType1 : CommsMessage
{
public override void ProcessMessage()
{
base.ProcessMessage();
// type 1 specific stuff.
}
}
// ...
void ProcessIncomingMessage(CommsMessage msg)
{
msg.ProcessMessage();
}
Arguably, you can call msg.ProcessMessage() directly, where you now call ProcessIncomingMessage, if there is nothing else in there to do.
To add to the excellent answers above:
In performance profiling I have noticed that using is followed by as actually resulted in lower performance than a single as followed by null check. Don't expect the compiler to automatically optimise anything. You are right to assume that in messaging code (or otherwise performance critical sections) that designing for speed is of paramount importance.
By far the fastest cast is a static cast which outperforms as i.e. var message = (SpecificType)baseMessage will outperform var message = baseMessage as SpecificType. This is a point of interest only as a static cast cannot help you in your case.
As two answers have already mentioned performing the above in a polymorphic fashion using a design pattern could be the best solution, as it only adds a virtual method call. Extracting the common method to an abstract class (or common method signature to interface) is by far the most elegant solution. There is an overhead of calling a virtual method but this can be mitigated by marking the specific methods on derived types using the sealed keyword.
Finally use generics where possible to eliminate casts as generic methods are a compile-time optimisation as opposed to run-time casting.
Best regards,
Consider this code.
public class Class1
{
public void ThisShouldNotCompileBecauseOrderWasVoilated()
{
Call2();
Call1();
}
public void ThisShouldCompileBecauseProperOrderIsPresent()
{
Call1();
Call2();
}
private void Call1()
{
// some code
}
private void Call2()
{
// some more code
}
}
What code (or attribute) should I add in Call1()/Call2() which ensures that compiler complains for 1st method and passes for 2nd method. There will be some rule list which compiler will have to refer if order is not correct. In this example the rule list can say "Call1 Call2", meaning call Call1() before Call2()
This is for C# language for .NET 4.0
Thanks!
There's nothing within normal C# that you can specify for this.
You may be able to use something like NDepend to detect this, but I'm not sure.
You can create your own attribute and mark your methods using it. Then create an FXCop rule. FXCop fully integrates with your build process, and as long as both calls are taking place within the same method, the rule should be fairly easy to flesh out.
the compiler can't enforce method call ordering, since in many cases it cannot determine statically what the call order is. For example:
public void whichOrder(boolean b)
{
if (b) call1();
if (!b) call2();
if (b) call2();
if (!b) call1();
}
If it's necessary that the methods are called in the correct order, you have a few choices:
document the call order, so that callers know what to do. This doesn't enforce the order, but at least makes coders aware of it.
add state to your object to remember which method was called last, and validate the current called method is allowed next. This enforces the method check at runtime.
Use a mock framework (e.g. Moq) to unit test your clients. This checks at build time that the order is correct.
Which approach you choose depends on how critical the correct ordering is, and the consequences of calling the methods in the wrong order.
An alternative is to rework your design so that method ordering doesn't become an issue. For example, wrap both methods up in a third, call3() that invokes call1() and call2() in the correct order. Or perhaps, have call2() invoke call1() if it has not already been executed, and have call1() check if it's already run, and return silently if it doesn't need to run. If clients invoke call2() then call1(), you still internally get the effect of call1() first (from call2()'s internal call to call1()) and the client's call to call1() results in a no op.
E.g.
public void call3()
{
call1();
call2();
}
or
public void call2()
{
call1();
// rest of call2's logic
}
private boolean call1Called = false;
pubic void call1()
{
if (!call1Called)
{
call1Called=true;
call1Impl();
}
}
This is not exactly what you are asking ... but you could introduce another class:
public class Another1
{
public Another2 Call1()
{
// some code
return new Another2();
// could pass 'this' to Another2 constructor so it has all state
}
}
public class Another2
{
public void Call2()
{
// some more code
}
}
Now, starting from an instance of Another1 you can only do obj.Call1().Call2() and never obj.Call2().Call1(). Better yet, this enforcement is in the IDE as you type. Take a look at 'fluent' patterns also.
So I've been dealing with several APIs recently provided by different software vendors for their products. Sometimes things are lacking, sometimes I just want to make the code more readable, and I'm trying to avoid a ton of static methods where they don't belong to "get what I need" from the APIs. Thus, I've found myself writing quite a few extension methods.
However, because there are many methods, and in the interest of keeping "my" methods separate from those of the API objects in terms of code readability, I came up with this little tidbit:
public class MyThirdPartyApiExtensionClass {
public static MyThirdPartyApiExtensionClass MTPAEC(this ThirdPartyApiClass value) {
return new MyThirdPartyApiExtensionClass(value);
}
private ThirdPartyApiClass value;
public MyThirdPartyApiExtensionClass(ThirdPartyApiClass extendee) {
value = extendee;
}
public string SomeMethod() {
string foo = value.SomeCrappyMethodTheProviderGaveUs();
//do some stuff that the third party api can't do that we need
return foo;
}
public int SomeOtherMethod() {
int bar = value.WowThisAPISucks(null);
//more stuff
return bar;
}
}
Then I can do things like:
string awesome = instanceOfApiObject.MTPAEC.SomeMethod();
and I have a clean separation of my stuff from theirs.
Now my question is.. does this seem like a good practice, improving code readability... or is this a bad idea? Are there any harmful consequences to doing this?
Disclaimer:
The code above is just to demonstrate the concept. Obviously there is better sanity checking and usefulness in the real thing.
I suppose the same level of separation could simply be done like this:
public static class MyThirdPartyApiExtensionClass {
public ThirdPartyApiClass MTPAEC(this ThirdPartyApiClass value) {
return value;
}
public string SomeMethod(this ThirdPartyApiClass value) {
string foo = value.SomeCrappyMethodTheProviderGaveUs();
//do some stuff that the third party api can't do that we need
return foo;
}
public int SomeOtherMethod(this ThirdPartyApiClass value) {
int bar = value.WowThisAPISucks(null);
//more stuff
return bar;
}
}
To answer your direct question, I think that going through the extra trouble to separate out your functionality from the basic functionality is a bad code smell. Don't worry about having your code separate from their code from a usage perspective. First it makes it that much harder to find what you're looking for since now there's two places to look for the same functionality and secondly the syntax makes it look like your extensions are operating on the MTPAEC property and not the core object (which they are).
My suggestion is to use actual Extension methods which allow you to have that but without having the additional constructor.
public static class ApiExtension
{
public static string SomeMethod(this ThirdPartyApiClass value)
{
string foo = value.SomeCrappyMethodTheProviderGaveUs();
//do some stuff that the third party api can't do that we need
return foo;
}
}
used by
var mine = new ThirdPartyApiClass();
mine.SomeMethod();
C# will do the rest.
Looking at your above suggestion you'll have to split the two classes out I think. One for providing extension groups using the extensions mechanism and another for providing each group of logic.
If you need to separate out yours from a glance then use a naming convention to make your look unique. Though upon hovering and through intellisense it will tell you that it is an extension method.
If you just want the separation of content like you have, then you'll need two classes.
public static class ApiExtensionder
{
public static MTPAEC(this ThirdPartyApiClass value)
{
return new MtpaecExtensionWrapper(value);
}
}
public class MtpaecExtensionWrapper
{
private ThirdPartyApiClass wrapped;
public MtpaecExtensionWrapper(ThirdPartyApiClass wrapped)
{
this.wrapped = wrapped;
}
public string SomeMethod()
{
string foo = this.wrapped.SomeCrappyMethodTheProviderGaveUs();
//do some stuff that the third party api can't do that we need
return foo;
}
}
When dealing with an API that you cannot modify, extension methods are a reasonable way to extend the API's expressiveness while staying relatively decoupled, IMHO.
The biggest issue with extension methods has to do with the fact that they are implicitly inferred to be available based on namespace inclusion (the using statements at the top of the file). As a result, if you simply forget to include a namespace, you can end up scratching your head wondering why there's not available.
I would also add that extension methods are not an obvious construct, and as a result developers don't commonly expect or anticipate them. However, with the increased use of LINQ, I would imagine more and more developers would be getting comfortable with their use.
My opinion is that you're adding an extra level of indirection needlessly. You want the extension methods to be available on the original objects... so why not put them there? Intellisense will let you know that the objects are extensions, for the rare case that you actually care.