Avoiding repetitive code in multiple similar methods (C#) - c#

Greetings everyone!
I have a set of a few (and potentially will have dozens more) of very similar methods in C#. They all built on almost identical pattern:
ResultObjectType MethodX(...input parameters of various types...)
{
nesting preparation code here...
{
{
resultObject = ExternalClass.GetResultForMethodX(input parameters of MethodX);
}
}
nesting result processing code here ...
return resultObject;
}
Repeating/identical parts: ResultObjectType, preparation code, result processing code.
Different parts: ExternalClass method to call, input parameter set (number of input parameters, their types).
Important: I am not in control of the method signatures – cannot change them.
I am trying to avoid repeating all blocks of similar code with something like this:
ResultObjectType MethodX(...input parameters of various types...)
{
return UniversalMethod(
new ExternalMethodDelegate(ExternalClass.GetResultForMethodX),
input parameters of MethodX...);
}
ResultObjectType UniversalMethod (Delegate d, input parameters of various types...)
{
nesting preparation code...
{
{
resultObject =
(d as ExternalMethodDelegate)(same input parameters as above);
}
}
nesting result processing code...
return resultObject;
}
So far I only managed to make it work in this manner in case where all parameters have the same known type at the time of coding. After a number of attempts to tackle this problem with generic delegates I am starting to think this is not possible to achieve. Even when my code compiles, it does not work at runtime. Any takers? Thanks in advance for your help!

Here's an example using generic delegates:
int MethodY(int something, int other)
{
return UniversalMethod(() => GetResultForMethodY(something, other));
}
string MethodX(string something)
{
return UniversalMethod(() => GetResultForMethodX(something));
}
T UniversalMethod<T>(Func<T> fetcher)
{
T resultObject;
//nesting preparation code here...
{
resultObject = fetcher();
}
//nesting result processing code here ...
return resultObject;
}
If ResultObjectType is always the same then you can remove all Ts.

Repeating/identical parts: ResultObjectType, preparation code, result processing code.
You should concentrate to make this parts as isolated as possible.
Another approach is code generation.

Related

How to stop a function midway and let the caller performs some tasks, get the result and proceed with rest of the function's job in C#

My current scenario is that, I am writing a library in C# that performs some task. But the tasks will need to run first, then halfway, it needs some input from the caller before it can continue with the rest of the tasks in the same function. How can I achieve this sort of scenario as I am not sure what is the keyword that I should search for.
For example in the library there is a function:
public bool DoSomething()
{
SomeWorkToBeDoneByLibrary_1();
SomeWorkToBeDoneByLibrary_2();
SomeWorkToBeDoneByLibrary_3();
// the caller now needs to perform a job and return a result before the library function can proceed
// the caller is the application consuming the library
string result = SomeWorkToBeDoneByCaller(); // ***How to achieve this?
SomeWorkToBeDoneByLibrary_4(result);
SomeWorkToBeDoneByLibrary_5(result);
SomeWorkToBeDoneByLibrary_6(result);
return true;
}
You could pass in a Func<string>callback parameter:
public bool DoSomething(Func<string> someWorkToBeDoneByCaller)
{
SomeWorkToBeDoneByLibrary_1();
SomeWorkToBeDoneByLibrary_2();
SomeWorkToBeDoneByLibrary_3();
// the caller now needs to perform a job and return a result before the library function can proceed
// the caller is the application consuming the library
string result = someWorkToBeDoneByCaller();
SomeWorkToBeDoneByLibrary_4(result);
SomeWorkToBeDoneByLibrary_5(result);
SomeWorkToBeDoneByLibrary_6(result);
return true;
}
Then the call would look like:
libobj.DoSomething(() => "foo");
or
libobj.DoSomething(MyFunc);
string MyFunc() { return "foo"; }
More about Func<T> here: https://learn.microsoft.com/en-us/dotnet/api/system.func-1
There are a few ways to achieve this. One is to feed the caller into the method
public bool DoSomething(MyClass callerClass)
{
SomeWorkToBeDoneByLibrary_1();
SomeWorkToBeDoneByLibrary_2();
SomeWorkToBeDoneByLibrary_3();
string result = callerClass.SomeWorkToBeDoneByCaller();
SomeWorkToBeDoneByLibrary_4(result);
SomeWorkToBeDoneByLibrary_5(result);
SomeWorkToBeDoneByLibrary_6(result);
return true;
}
I've used the above pattern for a few things, depending on your use case it can do the trick (depending on the nature of the work I'd reccomend making it async too but that's a whole other thing)
Another way is to pass in delegate methods (change the <> arguments to change the method's signature, and use Action if the method returns void)
public bool DoSomething(Func<ReturnClass,string,string> methodFromCallerClass)
{
SomeWorkToBeDoneByLibrary_1();
SomeWorkToBeDoneByLibrary_2();
SomeWorkToBeDoneByLibrary_3();
string result = methodFromCallerClass("foo","Bar");
SomeWorkToBeDoneByLibrary_4(result);
SomeWorkToBeDoneByLibrary_5(result);
SomeWorkToBeDoneByLibrary_6(result);
return true;
}
and you can use linq to make passing in the delegate easier if the signatures don't match 100% something like (x,y) => Foo(x,y,"bar") changes the method from having three parameters to two

Jump to certain line in code C#

I have a few methods that are called from within a few other methods. When in some of the methods a certain action is performed, I would like to go back to the very first method and skip the rest of the code. At the moment, I use booleans to check the "status" of the program but I would like to avoid this because the methods should be void since in essence they don't need to return anything. I found stuff like goto but that only works in the same method.
Question: is there a way to jump to a specific point in the code in a different method in C#? I found stuff on other languages but not a lot on C#.
Current situation:
void test1()
{
bool status = test2();
if (!status)
return; // the other stuff will not get done
Debug.WriteLine("Initialization OK");
}
bool test2()
{
bool status = test3();
if (!status)
return false; // the other stuff will not get done
// do other stuff
return true;
}
bool test3()
{
if (xxx)
return false; // the other stuff will not get done
else
// do other stuff
return true;
}
Wanted situation:
void test1()
{
test2();
// do other stuff
Debug.WriteLine("Initialization OK");
GOTOHERE:
Debug.WriteLine("Initialization NOT OK");
}
void test2()
{
test3();
// do other stuff
}
void test3()
{
if (xxx)
**GOTOHERE**; // Go directly to the location in test1() so that all unnecessary code is skipped
// do other stuff
}
I was surprised to learn that C# does actually support a GOTO command. But it is designed to allow exit from deep nested loops.
This article explains it and gives lots of examples: https://www.dotnetperls.com/goto
However
Unless you are still coding in 1970 then using GOTO is considered very bad practice. It makes code maintenance very difficult. And it even causes problems and performance issues, and makes life for the JIT compiler more difficult.
The go to statement as it stands is just too primitive, it is too much
an invitation to make a mess of one's program.
Edsger W. Dijkstra
Returning something from your method to indicate what you should do afterwards is exactly what you should do. Thus return a boolean indicating if test2 or test3 succeeded and use that value to indicate if you want to proceed further. Don´t use goto nowadays as it only leeds to spaghetti-code, that is hard to maintain. To determine under which circumstances control-flow should jump to GOTOHERE you´d need to scan your entire code for that specific goto-statement.
In your case you want to indicate if some initialization-code works correct. Thus you can also throw an exception:
void test3()
{
if (xxx)
throw new Exception("Some text");
// do other stuff
}
This way you don´t need to return anything from your method, but handle the exception appropriately:
void test1()
{
try { test2(); }
catch {
// some exception-handling such as logging
return;
}
Debug.WriteLine("Initialization OK");
}
This has the advantage that you don´t need to check in test2 if test3 succeeded, allowing you to let the exception bubble through your methods until it is finally handled by a catch. If no catch was found in the entire callstack your app will probably terminate.
C# does have the goto keyword, which works just like in other languages. Declare a label as label_you_want_to_jump_to:, and use goto label_you_want_to_jump_to (https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/goto).
Now that this is said, it is usually a bad idea to use goto, especially in such a way. Your problem might be solved more easily by refactoring a bit. Splitting test3 into two functions, reducing the amount of nesting might be such a way. You may also throw an exception in test3, and catch it in test1. It all depends on what you want to do.
If you get rid of the explicit bools (which are redundant), your (rather contrived) example looks a lot "cleaner" in my opinion:
void test1()
{
if (test2())
{
Debug.WriteLine("Initialization OK");
}
}
bool test2()
{
return test3();
}
bool test3()
{
return xxx;
}
I also prefer to use positive rather than negative conditions, so "if (true)" rather than "if (!false)". This avoids double negatives, which are harder to understand.
Effectively we are using Predicate Logic. We can combine our predicates (methods than return bool without side effects) using the normal logic operators. Consider this example:
bool test4()
{
if (test1())
{
if (test2())
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
We note that this is simply a logical conjunction (and) of test1 and test2, so can simply use the && conjunction operator to make this much clearer:
bool test4()
{
return test1() && test2();
}
Similarly for logical disjunction (or):
bool test5()
{
if (test1())
{
return true;
}
else if (test2())
{
return true;
}
else
{
return false;
}
}
We can write this instead as:
bool test5()
{
return test1() || test2();
}
I don't recommend it, but the simple answer to your question is to use a goto statement.
See: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/goto
You should, however, really be returning values from previous method calls that you can use to determine if you need to run other code.
You can also throw exceptions, but in general I'm not a fan of using them for control of flow unless the circumstance is exceptional (hence the name, I suppose). If you expect that control may flow this way or that, it is not exceptional.
I do understand your point but breaking the sequence of events (aka jumping) is not good practice. Your code becomes unreadable because the reader needs to jump from one place to another. There is a reason why you can't jump out of the current method:
What follows is a really simplified explanation. I am glosing over many details.
If you have knowledge about how the stack works you'll know that the runtime will push a new stack frame onto the stack for each new method invocation. That new stack frame contains the method's local variables as well as other things that are implementation details. If you want to jump to another method the runtime would need to push a new stack frame onto your stack in order to create those local variables for that method. So your goto would become a method invocation rather than a jump statement. Which is weird and not what you/we want. Use normal method invocations in such scenarios rather than jump statements.
There are widly accepted jumping statements like return, break and continue. goto is not one of them, although I consider goto case to be a valid solution in some cases.
Returning the information about what to do next is the correct behaviour here.
I do agree that returning a bool is not very expressive from a sematic perspective, at least not whith your current method names. Naming improvement suggestion:
void DoTest1();
bool TryTest2();
bool TryTest3();
FYI
bool flag;
void test1()
{
test2();
if (flag) {
// do other stuff
Debug.WriteLine("Initialization OK");
}
else {
Debug.WriteLine("Initialization NOT OK");
}
}
void test2()
{
test3();
if (flag) {
// do other stuff
}
}
void test3()
{
if (xxx)
return;
// do other stuff
flag = true;
}

How to know the Variable/Property Name which was passed to a Method?

private static void AssertNotNullAndAreEqual<T, TK>(T expected, TK actual)
{
Assert.IsNotNull(expected);
Assert.AreEqual(expected, actual);
}
I can call it using:
AssertNotNullAndAreEqual(expected.FirstName, actual.FirstName);
Is there any simple way that I can know the "FirstName" text of the expected object from within this method?
I'd need it for logging purposes and giving proper error messages from within this method.
The C# caller information doesn't help here.
I would rethink that approach, because this might bite back at some point - but if you're really keen on getting some degree of automation, you could try this:
private static void AssertNotNullAndAreEqual<T, TK>(Expression<Func<T>> expected,
Expression<Func<TK>> actual)
{
var memberExpression = expected.Body as MemberExpression;
if (memberExpression != null)
{
var expectedMemberName = memberExpression.Member.Name;
var expectedVal = expected.Compile()();
var actualVal = actual.Compile()();
Assert.IsNotNull(expectedVal);
Assert.AreEqual(expectedVal, actualVal);
//...
}
}
Now your calls would have to look as follows:
AssertNotNullAndAreEqual(() => expected.FirstName, () => actual.FirstName);
Few more caveat
a lot of stuff will not be checked until compile time (luckily type-safety is preserved). It's easy to write calls that will compile correctly, but fail at runtime.
as this is written, it won't work with variables - but if you decide to go this way, it would be pretty easy to write.
Please use at your own discretion :)
If you're using ToString() for another purpose (which I assume you are), you can define an interface and use it as a type constraint on AssertNotNullAndAreEqual(...), or alternately check to see if the objects passed to AssertNotNullAndAreEqual(...) have the interface.
You define an interface, say IDebugString, which has a ToDebugString() method, then you call that to retrieve the info to log.

Dependency Injection "nesting" in related methods

We're using DI and Unity to work with different dependencies (generally, database and repository classes, dto to entity mappers, etc)
Right now we're trying to create smaller functions that perform tasks that try to be independend from each other, in order to increase testability and also to avoid methods that have lots of different responsibilities, to avoid coupling
One question that I have is, how should DI be used when we have methods that rely on other inner methods, when the nesting is not trivial. For example, consider the following example (just a concept, not real working code):
public ProcessedOrder ProcessOrders(Order inputOrder)
{
foreach (var line in inputOrder.OrderLines)
{
var someData = LineProcessor(line);
}
}
public SomeData LineProcessor(OrderLine line)
{
/* do some stuff*/
var OtherData = ThingProcessor(null,line.SomeStuff);
var ret = new SomeData();
// assign values, more stuff
return ret;
}
public OtherData ThingProcessor(IDep1 someDependency, SomeStuff stuff)
{
someDependency = someDependency ?? ServiceLocator.Resolve<IDep1>();
var ret = someDependency.DoThings(stuff);
return ret;
}
Ok, so far the example shows that we have 3 functions, that could theoretically be called on their own. there's some injected dependency in the ThingProcessor, and if it's null then it tries to resolve it.
However, this is a somehow simple example, but I see something I don't like so much. For instance, I'm calling ThingProcessor with a null value in the first param. So I can say, ok, I modify the signature of LineProcessor to have it injected, so that he pass it in to the other function that needs it. However, he really doesn't need it, it's not its dependency but the function that he's calling.
So here I don't know what approach is the more correct one, if the one that i'm showing, or if I should pass the correlated dependencies across layers. If I do this last thing, then the outermost function will be a mess, because it'll have a long list of dependencies that it will feed to everyone that's below it.
However, the "null approach" I don't like very much, so I'm pretty sure that something's wrong somewhere, and there's probably a better way to design this.
What's the best approach??? Remember, all functions must be used independently (called on their own), so for example I may call just ThingProcessor at some point, or at another one only LineProcessor.
UPDATE :
public CommonPurposeFunctions(IDep1 dep1, IDep2 dep2 ....)
{
this.Dep1 = dep1;
this.Dep2 = dep2;
[...]
}
public ProcessedOrder ProcessOrders(Order inputOrder)
{
foreach (var line in inputOrder.OrderLines)
{
var someData = LineProcessor(line);
}
}
public SomeData LineProcessor(OrderLine line)
{
/* do some stuff*/
var OtherData = ThingProcessor(line.SomeStuff);
var ret = new SomeData();
var morethings = this.Dep2.DoMoreThings();
// assign values, more stuff
return ret;
}
public OtherData ThingProcessor(SomeStuff stuff)
{
var ret = this.Dep1.DoThings(stuff);
return ret;
}
The approach we use is constructor injection, then we store the dependency in a private member field. The container wires up the dependencies; so the number of classes and constructor parameters doesn't really matter.
This works for services. If the dependencies across calls have meaningful state, you will have to pass them in to each call. But, in that case, I'd question if the methods really need to be public methods in their own classes.
You want to end up with a design that eliminates the service locator and truly injects the dependencies.
Does the null object pattern help?
http://en.wikipedia.org/wiki/Null_Object_pattern

What is the most appropriate way to handle corrupt input data in a C# constructor?

I'm reading data in from a file and creating objects based on this data. The data format is not under my control and is occasionally corrupt. What is the most appropriate way of handling these errors when constructing the objects in C#?
In other programming languages I have returned a null, but that does not appear to be an option with C#.
I've managed to figure out the following options, but I would appreciate advice from more experienced C# programmers:
Option 1. Read the file inside the constructor and throw an exception when the source data is corrupt:
try
{
obj = Constructor(sourceFile);
... process object ...
}
catch (IOException ex)
{
...
}
Option 2. Create the object, then use a method to read data from the source file:
obj = Constructor();
obj.ReadData(sourceFile);
if (obj.IsValid)
{
... process object ...
}
or possibly throw exceptions on error:
obj = Constructor();
try
{
obj.Read(sourceFile);
... process object ...
}
catch
{
...
}
Option 3. Create the object using a static TryParse method:
if (ObjClass.TryParse(sourceFile, out obj))
{
... process object ...
}
and if so, should I implement option 3 internally using option 1?
public static bool TryParse(FileStream sourceFile, out ObjClass obj)
{
try
{
obj = Constructor(sourceFile);
return true;
}
catch (IOException ex)
return false;
}
I would do something along the lines of option 3):
class ObjectClass
{
protected ObjectClass(...constructor parameters your object depends on...)
{
}
public static ObjectClass CreateFromFile(FileStream sourceFile)
{
.. parse source file
if (parseOk)
{
return new ObjectClass(my, constructor, parameters);
}
return null;
}
}
And then use it like this:
ObjClass.CreateFromFile(sourcefile);
In general the constructor should take as parameters all properties which essentially define the class. Doing heavyweight calculations (like parsing a file) is best left to factory methods as it is usually not expected for the constructor to perform complex and potentially long running tasks.
Update: As mentioned in comments a better pattern is this:
public static ObjectClass CreateFromFile(FileStream sourceFile)
{
.. parse source file
if (!parseOk)
{
throw new ParseException(parseErrorDescription);
}
return new ObjectClass(my, constructor, parameters);
}
public static bool TryCreateFromFile(FileStream sourceFile, out ObjectClass obj)
{
obj = null;
.. parse source file
if (!parseOk)
{
return false;
}
obj = new ObjectClass(my, constructor, parameters);
return true;
}
I would not put anything into a constructor that might throw an exception - except for if something goes really wrong.
If your constructor has a possible return value other than a valid object, you should encapsulate it.
The safest way would probably be to create a factory method (public static function in the class that accepts a file reference and returns a new instance of the class or null). This method should first validate the file and its data and only then create a new object.
If the file data has a simple structure, you can first load it into some local variable and construct the object with this data.
Otherwise, you can still decide - inside of your factory method - if you rather want to try / catch the construction or use any of the other points mentioned above.
Both Options #1 and #3 are good choices and common in the .Net framework. It's also common to provide both for the same type. Consider Int32.TryParse and Int32.Parse. Providing both gives developers a bit more flexibility without detracting from the integrity of the type.
I would strongly advise you to avoid #2. This pattern forces both the type author and type consumer to handle instances of the type in multiple states
Constructed but not fully initialized
Initialized and valid
Initialized and invalid
This puts a burden on every consumer to deal with instances being in all different states (even if the response is to just throw). Additionally it forces a non-standard pattern on consumers. Developers have to understand your type is special and that it needs to be constructed and then initialized. It goes against the standard way objects are created in .Net.
Note for #3 though I would approach it a bit different. The exception form should be implemented in terms of the try form. This is the standard pattern when providing both options to the user. Consider the following pattern
class MyType {
struct ParsedData {
// Data from the file
}
public MyType(string filePath) : this(Parse(filePath)) {
// The Parse method will throw here if the data is invalid
}
private MyType(ParsedData data) {
// Operate on the valid data. This doesn't throw since the errors
// have been rooted out already in TryParseFile
}
public static bool TryParse(string filePath, out MyType obj) {
ParsedData data;
if (!TryParseFile(filePath, out data)) {
obj = null;
return false;
}
obj = new MyType(data);
return true;
}
private static ParsedData Parse(string filePath) {
ParsedData data;
if (!TryParseFile(filePath, out data)) {
throw new Exception(...);
}
return data;
}
private static bool TryParseFile(string filePath, out ParsedData data) {
// Parse the file and implement error detection logic here
}
}
From Microsoft Constructor Design Guidelines (MSDN),
Do throw exceptions from instance constructors if appropriate.
Constructors should throw and handle exceptions like any method. Specifically, a constructor should not catch and hide any exceptions that it cannot handle.
Factory Method is not the right way to approach this problem. See Constructors vs Factory Methods
From Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries
5.3 Constructor Design
Consider using a static factory method instead of a constructor if the
semantics of the desired operation do not map directly to the construction
of a new instance, or if following the constructor design guidelines
feels unnatural.
Do throw exceptions from instance constructors if appropriate.
.NET BCL implementations do throw exceptions from constructors
For example, the List Constructor (Int32), throws an ArgumentOutOfRangeException when the capacity argument of the list is negative.
var myList = new List<int>(-1); // throws ArgumentOutOfRangeException
Similarly, your constructor should throw an appropriate type of exception when it reads the file. For example, it could throw FileNotFoundException if the file does not exist at the specified location, etc.
More Information
Code Contracts
Throwing exceptions from constructor in .Net
Throwing ArgumentNullException in constructor?
Constructor parameter validation in C# - Best practices
All these solutions work, but as you said, C# doesn't allow to return null from a constructor. You either get an object or an exception. Since this is the C# way to go, I wouldn't choose option 3, because that merely mimics that other language you're talking about.
Lots of people [edit] among which is Martin, as I read in his answer :) [/edit] think it is good to keep your constructor clean and small. I'm not so sure about that. If your object is of no use without that data, you could read in the data in the constructor too. If you want to construct the object, set some options, and then read the data (especially with the possility to try again if the read fails), a separate method would be fine as well. So option 2 is a good possibility too. Even better maybe, depending mainly on taste.
So as long as you don't choose 3, choose the one you're the most comfortable with. :)

Categories