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,
Related
Sorry its a bit vague perhaps but its been bugging me for weeks. I find each project I tackle I end up making what I think is a design mistake and am pretty sure theres a bettwe way.
When defining a class thats serialized from an event source like a sinple json doc definition. Lets call it keys class with various defined integers, bools and strings. i have multiple methods that make use of this and i find that i constantly need to paas this class as an object by means of an overload. So method a calls methods b, method b doesnt need these objects but it calls method c which does... In doing this bad practice im passing these 'keys' objects to method b for the sole purpose of method c accessibility.
Im probably missing one major OOP fundamental :) any guidance or reading would be appreciated as im googled out!!
public class Keys
{
public child Detail { get; set; }
}
public class child
{
public string instance { get; set; }
}
//my main entry point
public void FunctionHandler(Keys input, ILambdaContext context)
{
methodA(input)
}
static void methodA(Keys input)
{
//some-other logic or test that doesn't need Keys object/class if (foo==bar) {proceed=true;}
string foo = methodB(input)
}
static string methodB(Keys input)
{
//here i need Keys do do stuff and I return a string in this example
}
What you do is not necessarily bad or wrong. Remember that in C# what you actually pass are references, not objects proper, so the overhead of parameter passing is really small.
The main downside of long call chains is that the program logic is perhaps more complicated than it needs to be, with the usual maintainability issues.
Sometimes you can use the C# type system to let the compiler or the run time choose the proper function.
The compiler is employed when you overload method() for two different types instead of defining methodA() and methodB(). But they are distinguished by the parameter type, so you need different Key types which may be (but don't have to be) related:
public class KeyA {/*...*/}
public class KeyB {/*...*/}
void method(KeyA kA) { /* do something with kA */ }
void method(KeyB kB) { /* do something with kB */ }
This is of limited benefit; that the functions have the same name is just syntactic sugar which makes it clear that they serve the same purpose.
The other, perhaps more elegant and versatile technique is to create an inheritance hierarchy of Keys which each "know" what a method should do.
You'll need a base class with a virtual method which will be overridden by the inheriting classes. Often the base is an interface just declaring that there is some method(), and the various implementing types implement a method() which suits them. Here is a somewhat lengthy example which uses a virtual Output() method so that we see something on the Console.
It's noteworthy that each Key calls a method of an OutputterI, passing itself to it as a parameter; the outputter class then in turn calls back a method of the calling object. That's called "Double Dispatch" and combines run-time polymorphism with compile-time function overloading. At compile time the object and it's concrete type are not known; in fact, they can be implemented later (e.g. by inventing another Key). But each object knows what to do when its callback function (here: GetData()) is called.
using System;
using System.Collections.Generic;
namespace DoubleDispatch
{
interface KeyI
{ // They actually delegate that to an outputter
void Output();
}
interface OutputterI
{
void Output(KeyA kA);
void Output(KeyExtra kE);
void Output(KeyI k); // whatever this does.
}
class KeyBase: KeyI
{
protected OutputterI o;
public KeyBase(OutputterI oArg) { o = oArg; }
// This will call Output(KeyI))
public virtual void Output() { o.Output(this); }
}
class KeyA : KeyBase
{
public KeyA(OutputterI oArg) : base(oArg) { }
public string GetAData() { return "KeyA Data"; }
// This will compile to call Output(KeyA kA) because
// we pass this which is known here to be of type KeyA
public override void Output() { o.Output(this); }
}
class KeyExtra : KeyBase
{
public string GetEData() { return "KeyB Data"; }
public KeyExtra(OutputterI oArg) : base(oArg) { }
/** Some extra data which needs to be handled during output. */
public string GetExtraInfo() { return "KeyB Extra Data"; }
// This will, as is desired,
// compile to call o.Output(KeyExtra)
public override void Output() { o.Output(this); }
}
class KeyConsolePrinter : OutputterI
{
// Note: No way to print KeyBase.
public void Output(KeyA kA) { Console.WriteLine(kA.GetAData()); }
public void Output(KeyExtra kE)
{
Console.Write(kE.GetEData() + ", ");
Console.WriteLine(kE.GetExtraInfo());
}
// default method for other KeyI
public void Output(KeyI otherKey) { Console.WriteLine("Got an unknown key type"); }
}
// similar for class KeyScreenDisplayer{...} etc.
class DoubleDispatch
{
static void Main(string[] args)
{
KeyConsolePrinter kp = new KeyConsolePrinter();
KeyBase b = new KeyBase(kp);
KeyBase a = new KeyA(kp);
KeyBase e = new KeyExtra(kp);
// Uninteresting, direkt case: We know at compile time
// what each object is and could simply call kp.Output(a) etc.
Console.Write("base:\t\t");
b.Output();
Console.Write("KeyA:\t\t");
a.Output();
Console.Write("KeyExtra:\t");
e.Output();
List<KeyI> list = new List<KeyI>() { b, a, e };
Console.WriteLine("\nb,a,e through KeyI:");
// Interesting case: We would normally not know which
// type each element in the vector has. But each type's specific
// Output() method is called -- and we know it must have
// one because that's part of the interface signature.
// Inside each type's Output() method in turn, the correct
// OutputterI::Output() for the given real type was
// chosen at compile time dpending on the type of the respective
// "this"" argument.
foreach (var k in list) { k.Output(); }
}
}
}
Sample output:
base: Got an unknown key type
KeyA: KeyA Data
KeyExtra: KeyB Data, KeyB Extra Data
b,a,e through KeyI:
Got an unknown key type
KeyA Data
KeyB Data, KeyB Extra Data
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.
We have a Web API library, that calls into a Business/Service library(where our business logic is located), which in turn calls a Data access library (Repository).
We use this type of data transfer object all over the place. It has a "Payers" property that we may have to filter (meaning, manipulate its value). I have gone about implementing that check as such, but it feels dirty to me, as I'm calling the same function all over the place. I have thought about either:
Using an attribute filter to handle this or
Making the RequestData a property on the class, and do the filtering in the constructor.
Any additional thoughts or design patterns where this could be designed more efficiently:
public class Example
{
private MyRepository _repo = new MyRepository();
private void FilterRequestData(RequestData data)
{
//will call into another class that may or may not alter RequestData.Payers
}
public List<ReturnData> GetMyDataExample1(RequestData data)
{
FilterRequestData(RequestData data);
return _repo.GetMyDataExample1(data);
}
public List<ReturnData> GetMyDataExample2(RequestData data)
{
FilterRequestData(RequestData data);
return _repo.GetMyDataExample2(data);
}
public List<ReturnData> GetMyDataExample3(RequestData data)
{
FilterRequestData(RequestData data);
return _repo.GetMyDataExample3(data);
}
}
public class RequestData
{
List<string> Payers {get;set;}
}
One way of dealing with repeated code like that is to use a strategy pattern with a Func (and potentially some generics depending on your specific case). You could refactor that into separate classes and everything but the basic idea looks like that:
public class MyRepository
{
internal List<ReturnData> GetMyDataExample1(RequestData arg) { return new List<ReturnData>(); }
internal List<ReturnData> GetMyDataExample2(RequestData arg) { return new List<ReturnData>(); }
internal List<ReturnData> GetMyDataExample3(RequestData arg) { return new List<ReturnData>(); }
}
public class ReturnData { }
public class Example
{
private MyRepository _repo = new MyRepository();
private List<ReturnData> FilterRequestDataAndExecute(RequestData data, Func<RequestData, List<ReturnData>> action)
{
// call into another class that may or may not alter RequestData.Payers
// and then execute the actual code, potentially with some standardized exception management around it
// or logging or anything else really that would otherwise be repeated
return action(data);
}
public List<ReturnData> GetMyDataExample1(RequestData data)
{
// call the shared filtering/logging/exception mgmt/whatever code and pass some additional code to execute
return FilterRequestDataAndExecute(data, _repo.GetMyDataExample1);
}
public List<ReturnData> GetMyDataExample2(RequestData data)
{
// call the shared filtering/logging/exception mgmt/whatever code and pass some additional code to execute
return FilterRequestDataAndExecute(data, _repo.GetMyDataExample2);
}
public List<ReturnData> GetMyDataExample3(RequestData data)
{
// call the shared filtering/logging/exception mgmt/whatever code and pass some additional code to execute
return FilterRequestDataAndExecute(data, _repo.GetMyDataExample3);
}
}
public class RequestData
{
List<string> Payers { get; set; }
}
This sort of thinking naturally leads to aspect oriented programming.
It's specifically designed to handle cross-cutting concerns (e.g. here, your filter function cuts across your query logic.)
As #dnickless suggests, you can do this in an ad-hoc way by refactoring your calls to remove the duplicated code.
More general solutions exist, such as PostSharp which give you a slightly cleaner way of structuring code along aspects. It is proprietary, but I believe the free tier gives enough to investigate an example like this. At the very least it's interesting to see how it would look in PostSharp, and whether you think it improves it at all! (It makes strong use of attributes, which extends first suggestion.)
(N.B. I'm not practically suggesting installing another library for a simple case like this, but highlighting how these types of problems might be examined in general.)
OK.. C# is not my forte and it's been a while since I got my head into this sort of thing and I have forgotten some things: I am struggling to get this too obey me :-) I am pretty sure what I want to do is possible within C# and I am pretty sure my abstracts and my interfaces are all to hell (I don't even know how to put the interface in but I know I need one)
ok here is the scenario
//abstract parent class
abstract class ActionType
{
/***
* this is a parent class not meant to ever be instaciated
*/
public abstract void action();
}
class ActionTypeSync : ActionType
{
public override void action()
{
Debug.WriteLine("doing sync");
}
}
class ActionTypeRead : ActionType
{
public override void action()
{
Debug.WriteLine("doing read");
}
}
the following does not work
ActionType action = getActionType(1);
ActionType secondaction = getActionType(2);
[ EDIT ]
actually I was being too brief it's THIS bit that didn't work with error
Error Argument 1: cannot convert from 'ActionType' to 'ActionTypeSync'
processThings(action);
//debug out put "doing sync"
processThings(secondaction);
//debug out put "doing sync"
public ActionType getActionType(int i)
{
if (i==1) return new ActionTypeSync();
if (i==2) return new ActionTypeRead();
}
public void processThings(ActionTypeSync action)
{
action.action();
}
public void processThings(ActionTypeRead action)
{
action.action();
}
[/ EDIT ]
How best do I need to restructure this.. please understand this is a an example for sake of brevity (as best as I could) I am summarising here - so some principles are better than some "why etc etc lectures" :-) thank you :-) I don't object to restructure in order to accommodate the polymorphic principle but I need this basic polymoprphic interface/class structure as is
Overlooking your syntactical errors, this is doing exactly what you told it to do.
It is calling the local action() on the specific type you instantiated, it doesn't do anything else because you haven't told it to (i.e. at no stage are you calling base.action()).
Edit:
Based on your edit.... ActionTypeSync and ActionTypeRead can both be cast down to ActionType, but ActionType cannot be cast back up to either of those derived types. You can pass one of the derived objects around as an ActionType and the overridden action() method will be called, but you can't cast it implicitly or explicitly to the derived type. To fix this just change your method signatures:
public void processThings(ActionType action)
{
action.action();
}
Because of this change you will now only need one method that will deal with both derived types because you have cast it down to its base type - IOW you can get rid of the processThings(ActionTypeRead action) method.
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.