C# Call Different Functions in Core Function - c#

In C#, How can I simplify GetData1() and GetData2() to one line function only?
Please see comments in GetData1 and GetData2, originally I have two write 3 lines in each function, but would like to use GetDataCore to simplify it.
public IEnumerable<int> GetDataCore(function passInFunction)
{
// many other steps
foreach (var sensor in sensors)
{
yield return sensor.passInFunction();
}
}
public IEnumerable<int> GetData1()
{
// many other steps
// TODO: use something like
// return GetDataCore(GetData1);
foreach (var sensor in sensors)
{
yield return sensor.GetData1();
}
}
public IEnumerable<int> GetData2()
{
// many other steps
// TODO: use something like
// return GetDataCore(GetData1);
foreach (var sensor in sensors)
{
yield return sensor.GetData2();
}
}

There's no need to write your own method to project all of the items in a sequence using a selector passed as a delegate. LINQ created such a method for you, called Select:
public IEnumerable<int> GetData1() {
return sensors.Select(sensor => sensor.GetData1());
}
But, to answer your question anyway, if function was a Func<Sensor, int>, then you could pass in a method that takes a sensor and transforms it into an integer, which you could do in each of your GetDataX methods, most likely using a lambada, as shown above.

Related

Avoid multiple similar foreach - C#

I apologize if I'm posting into the wrong community, I'm quite new here.
I have multiple methods using the same foreach loop, changing only the inner method I call:
public void CalculationMethod1()
{
foreach (Order order in ordersList)
{
foreach (Detail obj_detail in order.Details)
{
CalculateDiscount(obj_detail);
}
}
}
public void CalculationMethod2()
{
foreach (Order order in ordersList)
{
foreach (Detail obj_detail in order.Details)
{
CalculateTax(obj_detail);
}
}
}
Each inner method has different logic, database search, math calculations (not important here).
I'd like to call the methods above without repeating the foreach loop everytime, so I throught about the solution below:
public void CalculateMethod_3()
{
foreach (Order obj_order in ordersList)
{
foreach (Detail obj_detail in order.Details)
{
CalculateDiscount(obj_detail);
CalculateTax(obj_detail);
}
}
}
But I fall into a rule problem:
class Program
{
static void Main(string[] args)
{
Calculation c = new Calculation();
c.CalculateMethod_3();
c.AnotherMethod_4(); //It doesn't use objDetail
c.AnotherMethod_5(); //It doesn't use objDetail
c.CalculateMethod_6(); //Method 6 needs objDetail but respecting the order of the methods, so It must be after AnotherMethod_4 and AnotherMethod_5
}
}
How can I create a method to achieve my objective (I don't want to repeat code) respecting the rule above?
You can always pass a delegate to the method and then you can do basically whatever you want.
public void ApplyToDetails(Action<Detail> callback)
{
foreach (Order order in ordersList)
{
foreach (Detail obj_detail in order.Details)
{
callback(obj_detail);
}
}
}
Then to use you'd do something like this
ApplyToDetails(detail => CalculateTax(detail));
ApplyToDetails(detail =>
{
CalculateDiscount(detail);
CalculateTax(detail);
});
Delegates come in very handy in many cases and definitely in such a case. I know this has already been answered and rightly so, but here is an alternative for comparison. I have provided a link to give you some insight.
public class CalculationMethods
{
public delegate void CalculationDelegate(Detail method);
private Dictionary<string, CalculationDelegate> _methods;
public CalculationMethods
{
this._methods = new Dictionary<string, CalculationDelegate>()
{
{ "Discount", CalculateDiscount },
{ "Tax", CalculateTax }
};
}
public void Calculate(string method, Detail obj_detail)
{
foreach (Order order in ordersList)
{
foreach (Detail obj_detail in order.Details)
{
var m = this._methods.FirstOrDefault(item => item.Key == method).Value;
m(obj_detail);
}
}
}
}
Usage:
//Initialize
var methods = new CalculationMethods();
//Calculate Discount
methods.Calculate("Discount", obj_detail);
//Calculate Tax
methods.Calculate("Tax", obj_detail);
Side Note:
I would recommend some exception handling in case the method of calculation isn't found among the list of delegates. Example below: (Replace the calculate method with the following.)
public void Calculate(string method, Detail obj_detail)
{
foreach (Order order in ordersList)
{
foreach (Detail obj_detail in order.Details)
{
var m = this._methods.FirstOrDefault(item => item.Key == method).Value;
//Check if the method was found
if (m == null)
throw new ApplicationNullException("CalculationDelegate")
m(obj_detail);
}
}
}
Decent tutorial:
Delegates and Events
You can use delegates. (Google it - I don't have a development environment in front of me to run up a sample for you). Basically one method that takes a delegate to call:
Here is pseudo code...
public void CalculationMethod(delegate myFunction) // need to look up correct param syntax
{
foreach (Order order in ordersList)
{
foreach (Detail obj_detail in order.Details)
{
myFunction(); // Need to lookup correct calling syntax
}
}
}
I googled "c# delegate as parameter" and came up with http://msdn.microsoft.com/en-us/library/ms173172.aspx which seems to be a reasonable explanation.
As Darren Kopp says, you can use delegates. However, in the case that you are calling a method with a parameter, you can call it directly (you don't need the lambda expression).
With public void ApplyToDetails(Action<Detail> callback) { ... }:
ApplyToDetails(Method_1); // Uses objDetail
ApplyToDetails(d => Method_2()); // Doesn't use objDetail
ApplyToDetails(d => Method_3()); // Doesn't use objDetail
ApplyToDetails(Method_4); // Uses objDetail
Note that you must not place parameter braces after the methods you pass as delegate!
You could use delegates as the other answers have provided but I believe in your case doing so will lead to overly confusing code. Your code is cleaner and more readable if you redeclare the foreach loops in each method. Only if you were copy-pasting portions of the internals would I say you run the risk of code duplication.
Think about it this way: If you created a method passing in a delegate, what would the name of this method be called? It is a method that does something for each Detail in each Order you pass in and should be named something like DoSomethingForEachDetailInOrders(). What kind of class would this method exist for? You don't know what it is you're actually doing in the delegate, so the purpose of this class would have to be more framework-style code, which your app does not appear to be complex enough to warrant.
Additionally, if you were debugging this code or reading through it, instead of being able to see 2 foreach loops inside the method you are reading, you have to go scroll to the definition of the delegate, read that, and then go back to your method and resume reading.
Edit: I originally answered this question by downplaying the duplication of the foreach loops in the hopes that OP would not add additional complexity to his app attempting to make it follow "best practices." I didn't go deeper because the code requires a more intrusive refactor for maintainability. The foreach loop code smell stems from other problems as detailed in the comments below this answer. I still stand by my opinion that adding the delegate method is less desirable than the duplicated loops because the delegate method option is pretty much textbook boilerplate.
Added a code example to explain how the code should be refactored if maintainability is a concern:
public decimal CalculateDiscount(IEnumerable<Order> ordersList)
{
return ordersList.SelectMany(order => order.Details).Sum(detail => detail.Discount);
}
public decimal CalculateTax(IEnumerable<Order> ordersList)
{
return ordersList.SelectMany(order => order.Details).Sum(detail => detail.Total) * taxRate;
}
If you ABSOLUTELY MUST HAVE a custom function for getting all details for orders (could be refactored to an extension method):
public IEnumerable<Detail> GetDetailsForOrders(IEnumerable<Orders> orderList)
{
foreach(var order in orderList)
{
foreach (var detail in order.Details)
{
yield return detail;
}
}
}
public decimal CalculateDiscount(IEnumerable<Order> ordersList)
{
return GetDetailsForOrders(ordersList).Sum(detail => detail.Discount);
}
public decimal CalculateTax(IEnumerable<Order> ordersList)
{
return GetDetailsForOrders(ordersList).Sum(detail => detail.Total) * taxRate;
}

Any performance issue using static function Objects

I have a piece of code like this.
I write this because I love extension methods and lambda expression:
public static class TuneingRules
{
public static Func<HtmlNode, bool> IsNodeHavingClearNone = (node) =>
{
if (node.HasAttributes)
{
// HtmlAttribute atr = item.Attributes.Where(at => at.Name == "id" && at.Value == "hello").FirstOrDefault();
HtmlAttribute atr = node.Attributes.Where(at => at.Name == "style").FirstOrDefault();
if (atr != null)
{
return Regex.Match(atr.Value, "clear\\s*:\\s*none;").Success;
}
}
return true;
};
}
and extension method like this.
public static class ExtensionMethods
{
#region Ignoring Rules
public static bool Ignore(this HtmlNode Node, Func<HtmlNode,bool> func) {
return func(Node);
}
#endregion
}
now I have two approaches to use this piece of code..
1 case
if (!htmlNode.Ignore(TuneingRules.IsNodeHavingClearNone)){
//then do somethings
}
// here i am open to write lambda expression like this.
if (!htmlNode.Ignore( node => node.innerText =="" ){
//then do somethings
}
2 case
if (!TuneingRules.IsNodeHavingClearNone(htmlNode)) {
//then do something
}
I'm afraid that there are any performance issues if TuneingRules
has many static Func<HtmlNode,bool> objects. Do i need to refactor my code?
In the first case there is an extra call going through ignore function...
but in the second case i can call the function object directly.
Or is there another way to write this code in order to stick with lambda as well as extension methods?
No, there is no performance issue.
There will be a small performance hit the first time that you use the TuneingRules class, as the static constructor will be called and initialise all the static variables. That should however be quite small compared to the actual work that the function does.
Likewise, doing one extra method call is negligible compared to the work that the function does. It's even possible that the extension method call will be inlined by the JIT compiler, so that the executed code will actually do the same thing as in your second case.

Resharper removes yield from foreach. Why?

I recently learned about yield and then created the following test console program:
public static string Customers = "Paul,Fred,Doug,Mark,Josh";
public static string Admins = "Paul,Doug,Mark";
public static void Main()
{
var test = CreateEfficientObject();
Console.WriteLine(test.Admins.FirstOrDefault());
//Note that 'GetAllCustomers' never runs.
}
public static IEnumerable<string> GetAllCustomers()
{
var databaseFetch = Customers.Split(',');
foreach (var s in databaseFetch)
{
yield return s;
}
}
public static IEnumerable<string> GetAllAdmins()
{
var databaseFetch = Admins.Split(',');
foreach (var s in databaseFetch)
{
yield return s;
}
}
static LoginEntitys CreateEfficientObject()
{
var returnObject = new LoginEntitys {};
returnObject.Admins = GetAllAdmins();
returnObject.Customers = GetAllCustomers();
return returnObject;
}
}
public class LoginEntitys
{
public IEnumerable<String> Admins { get; set; }
public IEnumerable<String> Customers { get; set; }
}
Yet I noticed Resharper wants to convert my foreach loops to :
public static IEnumerable<string> GetAllCustomers()
{
var databaseFetch = Customers.Split(',');
return databaseFetch;
}
Why does Resharper want to remove yield from this case? It changes the functionality completely as it will no longer lazy load without yield. I can only guess that either
A) I am using yield incorrectly/in bad pratice
B) It's a Resharper bug/suggestion that can just be ignored.
Any insight would be great.
You are correct that this proposed transformation changes the functionality of the code in subtle ways, preventing it from deferring the evaluation of the properties and performing the Split from being evaluated as early.
Perhaps those that implemented it were well aware that it was a change in functionality and felt that it was still a useful suggestion, one that could be ignored if the existing semantics were important, or if they actually failed to realize that the semantics were being altered. There's no good way for us to know, we can only guess. If those semantics are important for your program, then you are correct to not make the suggested transformation.
I think Resharper is being a bit dumb here, in the sense that its applying a standard "convert foreach to LINQ" transform without being aware of the context.
It doesn't suggest the same edits for a while loop:
public static IEnumerable<string> ReadLineFromFile(TextReader fileReader)
{
using (fileReader)
{
string currentLine;
while ((currentLine = fileReader.ReadLine()) != null)
{
yield return currentLine;
}
}
}
I guess the next iteration of Resharper which uses Roslyn will be much more context aware.
Thanks #servy for an engaging and refreshing discussion!
The code in your example is not calling the iterator on the IEnumerable you are returning. If you were using the result of GetAllAdmins() in a LINQ query for example the yield would be useful because execution of the expression could resume on each iteration.
I would imagine Resharper is just suggesting you remove unused code.

Can methods be called via an array in C#?

I have a program that will need to run different methods depending on what I want it to talk to, and I want to know if there is a way to store some sort of method pointer or something of that sort in an array. So I want an array where each element would be something like this:
[Boolean: Do_this?] [Function_pointer] [Data to pass to the function]
So basically, I can put this into a for loop and not call each function individually. Another block of code would fill in the Boolean of whether to run this function or not, and then my for loop would go through and run the function with its appropriate data if the Boolean is true.
I know delegates are similar to function pointers, but if that is the answer here, I'm not entirely sure how I would construct what I want to construct.
Is this possible in C#?
Sure is, although, to do it this way, you need all methods to have the same signature:
Lets say you had two methods:
public int Moop(string s){ return 1; }
public int Moop2(string s){ return 2; }
You could do:
var funcs = new Func<string, int>[]{ Moop, Moop2 };
And to call:
var val = funcs[0]("hello");
You could declare a specific object type to hold in a delegate, a flag that indicates whether to do that or now and the data. Note that what you are describing is very similar to events as they are also defined by a callback and some event data.
The skeletal model would look something like this, assuming all methods you want to call have the same signature (you can work around that, if you need a whole bunch of various signatures by using reflection):
// This reflects the signature of the methods you want to call
delegate void theFunction(ActionData data);
class ActionData
{
// put whatever data you would want to pass
// to the functions in this wrapper
}
class Action
{
public Action(theFunction action, ActionData data, bool doIt)
{
this.action = action;
this.data = data;
this.doIt = doIt;
}
public bool doIt
{
get;
set;
}
public ActionData data
{
get;
set;
}
public theFunction action
{
get;
set;
}
public void run()
{
if (doIt)
action(data);
}
}
And a regular use case would look something like this:
class Program
{
static void someMethod(ActionData data)
{
Console.WriteLine("SUP");
}
static void Main(string[] args)
{
Action[] actions = new Action[] {
new Action(Program.someMethod, new ActionData(), true)
};
foreach(Action a in actions)
a.run();
}
}
Yes, you can.
If all your functions share the same signature you might want to store delegates in your collection, otherwise I would go for System.Reflection.MethodInfo, which you can use later on by calling Invoke method. Parameters would be stored as array of objects - that's what Invoke expects.
If using reflection is too slow you can use Reflection.Emit to generate dynamic methods at runtime.
I would just create a List<Action>. Action is a delegate that takes no parameters and returns no results. You can use currying and lambdas such that the actual actions can call a method that has parameters. In the case where you don't actually want to run it, just don't add it to the list in the first place (or add an action that does nothing I guess).
To add an item it might look something like:
list.Add(() => someobject.someMethod(firstArgument, secondArgument));
list.Add(() => anotherObject.anotherMethod(oneArgument));
Then you can just run all of the actions when you want to:
foreach(Action action in list)
{
action();
}
This is exactly what you would use delegates for. Delegates are, more or less, type-checked function pointers. You can create some delegates and put them into an array.
Func<int, int> [] funcs = new Func<int,int>[] { x => 2 * x, x => x * x };
foreach(var fn in funcs)
{
Console.WriteLine(fn(3));
Console.WriteLine(fn(8));
}

How to know if an enumerator has reached the end of the collection in C#?

I am porting a library from C++ to C#. The old library uses vectors from C++ and in the C# I am using generic Dictionaries because they're actually a good data structure for what I'm doing (each element has an ID, then I just use using TypeDictionary = Dictionary<String, Type>;). Now, in the C# code I use a loop like this one
TypeDictionary.Enumerator tdEnum = MyTypeDictionary.GetEnumerator();
while( tdEnum.MoveNext() )
{
Type element = typeElement.Current.Value;
// More code here
}
to iterate through the elements of the collection. The problem is that in particular cases I need to check if a certain enumerator has reached the end of the collection, in C++ I would have done a check like this:
if ( tdEnum == MyTypeDictionary.end() ) // More code here
But I just don't know how to handle this situation in C#, any ideas?
Thank you
Tommaso
Here's a pretty simple way of accomplishing this.
bool hasNext = tdEnum.MoveNext();
while (hasNext) {
int i = tdEnum.Current;
hasNext = tdEnum.MoveNext();
}
I found an online tutorial that also may help you understand how this works.
http://www.c-sharpcorner.com/UploadFile/prasadh/Enumerators11132005232321PM/Enumerators.aspx
You know that you're at the end of an iterator when MoveNext() returns false. Otherwise you need to upgrade to a more descriptive data structure like IList<T>.
I have a "smart iterator" class in MiscUtil which you may find useful. It lets you test whether you're currently looking at the start or end of the sequence, and the index within the sequence. See the usage page for more information.
Of course in most cases you can just get away with doing this manually using the result of MoveNext(), but occasionally the extra encapsulation comes in handy.
Note that by necessity, this iterator will always have actually consumed one more value than it's yielded, in order to know whether or not it's reached the end. In most cases that isn't an issue, but it could occasionally give some odd experiences when debugging.
Using the decorator pattern to hold a value if the enumerator has ended is a valid approach.
Since it implements IEnumerator, you won't find difficulties to replace it in your code.
Here's a test class:
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MyDictionary = System.Collections.Generic.Dictionary<int, string>;
using MyKeyValue = System.Collections.Generic.KeyValuePair<int, string>;
namespace TestEnumerator
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestingMyEnumeradorPlus()
{
var itens = new MyDictionary()
{
{ 1, "aaa" },
{ 2, "bbb" }
};
var enumerator = new EnumeradorPlus<MyKeyValue>(itens.GetEnumerator());
enumerator.MoveNext();
Assert.IsFalse(enumerator.Ended);
enumerator.MoveNext();
Assert.IsFalse(enumerator.Ended);
enumerator.MoveNext();
Assert.IsTrue(enumerator.Ended);
}
}
public class EnumeradorPlus<T> : IEnumerator<T>
{
private IEnumerator<T> _internal;
private bool _hasEnded = false;
public EnumeradorPlus(IEnumerator<T> enumerator)
{
_internal = enumerator;
}
public T Current
{
get { return _internal.Current; }
}
public void Dispose()
{
_internal.Dispose();
}
object System.Collections.IEnumerator.Current
{
get { return _internal.Current; }
}
public bool MoveNext()
{
bool moved = _internal.MoveNext();
if (!moved)
_hasEnded = true;
return moved;
}
public void Reset()
{
_internal.Reset();
_hasEnded = false;
}
public bool Ended
{
get { return _hasEnded; }
}
}
}
Coming from C++ you might not be up to date on C# syntax. Perhaps you could simply use the foreach construct to avoid the test all together. The following code will be executed once for each element in your dictionary:
foreach (var element in MyTypeDictionary)
{
// More code here
}

Categories

Resources