Im still kinda new to c# and there's something I cant quite get to grips with:
In VBA for example, if there is a bit of code I need throughout an app I would put it in a function then call it where ever I need it just by using the name of the function, eg
Sub Something()
If variable = x then
RunMyFunction
end if
End Sub
Is there a similar way of calling re-usable code in c#? I do realise its a completely different beast to what Ive worked with before
thanks
private void Something()
{
if (variable == x)
{
RunMyFunction();
}
}
private void RunMyFunction()
{
// does something
}
In other words - it is basically the same. You define your resuable function as a method (RunMyFunction above) and then call it by name (with parenthesis).
Yes C# comes with functions as well. Sub is actually a function with void "return value".
So crude translation of your code to C# will be:
string RunMyFunction()
{
return "hello";
}
void Something(variable, x)
{
if (variable == x)
{
string value = RunMyFunction();
//.....
}
}
Yes, I sometimes create a new class called CommonFunctions.cs, and inside this class I would have the methods:
public class CommonFunctions
{
public static void Something(int Variable)
{
if(Variable == 5)
CommonFunctions.RunAnother();
}
public static void RunAnother()
{
}
}
Here is an example of a function:
public int AddNumbers(int number1, int number2)
{
int result = number1 + number2;
if(result > 10)
{
return result;
}
}
You might find this article useful:
http://csharp.net-tutorials.com/basics/functions/
The biggest departure you'll need to make from VBA is that C# is truly object-oriented. You'll have to get used to the idea of functions being a member of a class that you have to instantiate (in most cases).
If your function do not return value use void:
private void FunctionName ()
{
// Do something...
}
If function return value than function have value type before function name:
private int FunctionNameReturnInt(int a, int b)
{
// Do something...
int res = a + b;
return num;
}
...
// Calling functions
FunctionName();
int res;
res = FunctionNameReturnInt(1,2);
`
Related
I have a function that takes a list of Func<bool> each with an attached value. It iterates the list and returns the attached value if a delegate returns true. Some of these delegates call the same function with the same parameters how do I best memoize the result of such calls within the scope of the TryFindValue method?
The return value of the functions may change between calls to TryFindValue, but they will not change while iterating the list. I would like to avoid generating garbage (boxing/unboxing by casting to object for example). Ideally, I would only have to use the space for memoized values in the scope of TryFindValue and not for the entire lifetime of each delegate for example, but I do not know if that is possible.
public class SomeClass
{
public bool TryFindValue(List<CondValue> list, out int value)
{
for (int i = 0; i < list.Count; i++)
{
var condValue = list[i];
if (condValue.cond())
{
value = condValue.value;
return true;
}
}
value = default(int);
return false;
}
}
public class SomeOtherClass
{
private List<CondValue> list;
public SomeOtherClass()
{
list = new List<CondValue>();
// SomeMethod(3) will be calculated twice
list.Add(new CondValue(() => SomeMethod(3) > SomeOtherMethod(), 42));
list.Add(new CondValue(() => SomeMethod(3) < SomeThirdMethod(), 35));
}
private float SomeMethod(int value)
{
// Implementation... (uses some internal or global state)
}
private int SomeOtherMethod()
{
// Implementation... (uses some internal or global state)
}
private int SomeThirdMethod()
{
// Implementation... (uses some internal or global state)
}
}
public struct CondValue
{
public Func<bool> cond;
public int value;
public CondValue(Func<bool> func, int value)
{
this.func = func;
this.value = value;
}
}
If you turn CondValue.cond into an expression tree instead of a Func then maybe you could make some complicated solution. I have no experience doing so and I wouldn't suggest venturing out on that adventure. Apart from that I don't see a good solution to only keep it cached/memorized within the lifetime of a single call to TryFindValue.
I would rather ask you:
Is there any good reason you have the current setup?
It seems like an unnecessarily complicated setup. Since you've only shown a very abstract example it's difficult to suggest a better alternative.
Would e.g. SomeMethod(3) not always return the same value?
You could wrap that method in some caching logic (e.g. with help from PostSharp). But if it doesn't consistently return the same value, you'd have to clear that cache when necessary, which makes it harder to maintain.
Instead of having individual conditions that return true or false with an attached value you could just return the value or null. How does that help? For the following solution, I am assuming that the delegates in the list that call the same function are added to the list together in the same function (here in the constructor SomeOtherClass). From there you could batch together delegates that call the same functions with the same parameters in an if-else if code block and manually "memoize" the result of the function at the top of the delegate.
Delegates that call the same functions with the same parameters smells like they are related in this if-else if relationship anyway. I have added SomeFourthMethod to show how to still compactly add a single conditional individually.
If you have suggestions to improve the details of this solution (using something else than nullable, etc.) then feel free to suggest it in a comment.
If all the conditions are always independent and just happen to sometimes call the same function, then this solution might not be appropriate. Otherwise, it is the simplest most effective solution I can think of.
public class SomeClass
{
public bool TryFindValue(List<Func<int?>> list, out int value)
{
for (int i = 0; i < list.Count; i++)
{
var func = list[i];
int? ret = func();
if (ret.HasValue)
{
value = ret.Value;
return true;
}
}
value = default(int);
return false;
}
}
public class SomeOtherClass
{
private List<Func<int?>> list;
public SomeOtherClass()
{
list = new List<Func<int?>>();
Add(() =>
{
float memoized = SomeMethod(3);
if (memoized > SomeOtherMethod())
return 42;
else if (memoized < SomeThirdMethod())
return 35;
return null;
});
Add(() => SomeFourthMethod() > 4, 72);
}
private void Add(Func<int?> snippet)
{
list.Add(snippet);
}
private void Add(Func<bool> cond, int value)
{
list.Add(() =>
{
if (cond())
return value;
return null;
});
}
private float SomeMethod(int value)
{
// Implementation... (uses some internal or global state)
}
private int SomeOtherMethod()
{
// Implementation... (uses some internal or global state)
}
private int SomeThirdMethod()
{
// Implementation... (uses some internal or global state)
}
private int SomeFourthMethod()
{
// Implementation... (uses some internal or global state)
}
}
I was going over some code that a knowledgeable colleague wrote and I came across a technique I found confusing. Here is a snippet of code ...
public class TaxController : ApiController
{
private StateTaxApi taxApi = new taxApi();
[HttpGet]
public async Task<IEnumerable<String>> GetStatesOwedTax(String taxId, String clientId)
{
try
{
return await taxApi.GetStatesOwedTax(clientId, GetTaxId(), GetClientId());
}
catch (Exception e)
{
throw new ApiException(HttpStatusCode.BadRequest, "Could not get tax states", e);
}
}
private String GetClientId()
{
try
{
return Request.Headers.GetValues("client-id").FirstOrDefault();
}
catch (InvalidOperationException e)
{
// TODO: Handle error here
}
return null;
}
private String GetTaxId()
{
return GetSessionValue("taxId") as String;
}
private Object GetSessionValue(String key)
{
var context = Request.Properties["MS_HttpContext"] as HttpContextWrapper;
var session = context.Session;
return session[key];
}
}
Here you can see the methods are being passed as parameters to the method GetStatesOwedTax():
return await taxApi.GetStatesOwedTax(clientId, GetTaxId(), GetClientId());
I thought the only way to do this was to use a delegate to represent the method being passed in as a parameter. I see no mention of Func(string) defining the delegates. What am I missing?
The method isn't being passed, the result of the method is being passed. As simple as that is to say, I find an example always serves better.
public void Start()
{
var result = DoMath(GetX(), GetY());
}
public int GetX()
{
return 1;
}
public int GetY()
{
return 2;
}
public int DoMath(int x, int y)
{
return x + y;
}
As you can see in the example, DoMath() needs two ints passed into it. In lieu of
public void Start()
{
var x = GetX();
var y = GetY();
var result = DoMath(x, y);
}
you can do the method calls directly in the parameters of the DoMath() method.
Now, whether this is simpler, better, good/bad practice all comes down to personal style and overall complexity. If it's very readable then you can save space by doing this, but it does risk muddying up the waters and not being as apparent to what you're doing. So I can't say if you should or should not do it, just saying that you can do it.
As mentioned by Vilx in the comments, an easy way to tell if the method is being passed vs the results of the method are the inclusion of the parenthesis. If they are there (as they are in this case) then it means the method will be evaluated and its result used.
I am creating a C# library with some reusable code and was trying to create a method inside a method. I have a method like this:
public static void Method1()
{
// Code
}
What I would like to do is this:
public static void Method1()
{
public static void Method2()
{
}
public static void Method3()
{
}
}
Then I could choose either Method1.Method2 or Method1.Method3. Obviously the compiler isn't happy about this, any help is much appreciated. Thanks.
If by nested method, you mean a method that is only callable within that method (like in Delphi) you could use delegates.
public static void Method1()
{
var method2 = new Action(() => { /* action body */ } );
var method3 = new Action(() => { /* action body */ } );
//call them like normal methods
method2();
method3();
//if you want an argument
var actionWithArgument = new Action<int>(i => { Console.WriteLine(i); });
actionWithArgument(5);
//if you want to return something
var function = new Func<int, int>(i => { return i++; });
int test = function(6);
}
Yes, when C# 7.0 is released, Local Functions will allow you to do that. You will be able to have a method, inside a method as:
public int GetName(int userId)
{
int GetFamilyName(int id)
{
return User.FamilyName;
}
string firstName = User.FirstName;
var fullName = firstName + GetFamilyName(userId);
return fullName;
}
Note that public (and similar modifiers) are not supported C# programming guide:
Because all local functions are private, including an access modifier, such as the private keyword, generates compiler error CS0106, "
This answer was written before C# 7 came out. With C# 7 you can write local methods.
No, you can't do that. You could create a nested class:
public class ContainingClass
{
public static class NestedClass
{
public static void Method2()
{
}
public static void Method3()
{
}
}
}
You'd then call:
ContainingClass.NestedClass.Method2();
or
ContainingClass.NestedClass.Method3();
I wouldn't recommend this though. Usually it's a bad idea to have public nested types.
Can you tell us more about what you're trying to achieve? There may well be a better approach.
You can define delegates within your method with complete code and call them if you want.
public class MyMethods
{
public void Method1()
{
// defining your methods
Action method1 = new Action( () =>
{
Console.WriteLine("I am method 1");
Thread.Sleep(100);
var b = 3.14;
Console.WriteLine(b);
}
);
Action<int> method2 = new Action<int>( a =>
{
Console.WriteLine("I am method 2");
Console.WriteLine(a);
}
);
Func<int, bool> method3 = new Func<int, bool>( a =>
{
Console.WriteLine("I am a function");
return a > 10;
}
);
// calling your methods
method1.Invoke();
method2.Invoke(10);
method3.Invoke(5);
}
}
There is always an alternative of using a nested class within a class that will not be visible from outside and calling its methods, like:
public class SuperClass
{
internal static class HelperClass
{
internal static void Method2() {}
}
public void Method1 ()
{
HelperClass.Method2();
}
}
As of C# 7.0 you can do that:
public static void SlimShady()
{
void Hi([CallerMemberName] string name = null)
{
Console.WriteLine($"Hi! My name is {name}");
}
Hi();
}
This is called local functions, that is just what you were looking for.
I took the example from here, but further informatin can be found here and here.
Why you don't use classes?
public static class Helper
{
public static string MethodA()
{
return "A";
}
public static string MethodA()
{
return "A";
}
}
Now you can acces MethodA via
Helper.MethodA();
Older thread, but C# does have the concept of nested functions
Func<int> getCalcFunction(int total, bool useAddition)
{
int overallValue = 0;
if (useAddition)
{
Func<int> incrementer = new Func<int>(() =>
{
overallValue += total;
return overallValue;
});
return incrementer;
}
else
{
Func<int> decrementer = new Func<int>(() =>
{
overallValue -= total;
return overallValue;
});
return decrementer;
}
}
private void CalcTotals()
{
Func<int> decrem = getCalcFunction(30, false);
int a = decrem(); //result = -30
a = decrem(); //result = -60
Func<int> increm = getCalcFunction(30, true);
int b = increm(); //result = 30
b = increm(); //result = 60
}
Your nearly there
public static void Method1()
should be
public static class Method1{}
Don't you want to use nested class instead?
That's said, you seem to not respect the Single Responsibility Principle because you want a single method do more than one thing at a time.
Why don't you just Run a method within another
public void M1()
{
DO STUFF
}
public void M1()
{
DO STUFF
M1();
}
I have 4 methods which have similar code
private void LogExceptions(ObjA.Input input, int customerId)
{
//ObjA is a big object, thats why I try not to send the whole object in this method
Log(input);
Log(ObjA.Exceptions);
}
private void LogExceptions(ObjB.Input input, int customerId)
{
//ObjB is a big object, thats why I try not to send the whole object in this method
Log(input);
Log(ObjB.Exceptions);
}
and so on
I am not able to make it a template method such as
private void LogExceptions<T1,T2>(T1 input, int customerId) whereas T1:ObjA.Input,ObjB.Input
{
Log(T1);
Log(T2);
}
How to do it or is there any other way ?
Any help is appreciated in advance .
I don't think my question was helping get proper answers....
Here is the exact code....
private void LogExceptions(AccARef.Response response)
{
StringBuilder sbErrors = null;
if (response.ValMethod != null && response.ValMethod.IsValid == false)
{
if (response.ValMethod.Errors.Count() > 0)
{
sbErrors = new StringBuilder();
foreach (AccARef.Exception exp in response.ValMethod.Errors)
{
sbErrors.Append(" * " + exp.Message + exp.StackTrace + " ");
Console.WriteLine(strError.ToString())
}
}
}
}
private void LogExceptions(AccBRef.Response response)
{
StringBuilder sbErrors = null;
if (response.ValMethod != null && response.ValMethod.IsValid == false)
{
if (response.ValMethod.Errors.Count() > 0)
{
sbErrors = new StringBuilder();
foreach (AccBRef.Exception exp in response.ValMethod.Errors)
{
sbErrors.Append(" * " + exp.Message + exp.StackTrace + " ");
Console.WriteLine(strError.ToString())
}
}
}
}
Now AcctBRef and AcctARef cannot implement a common interface as they are not my objects. Or if they are no my objects, can I still decorate them to be mine ?
You don't even need generics in this case, if ObjA and ObjB either inherit from the same base blass or interface.
If you have
interface IBaseClass
{
IEnumerable<Something> Exceptions {get;set;}
InputType Input {get;set;}
}
class A : IBaseClass {}
class B : IBaseClass {}
You can just use this for your LogExceptions signature:
void LogExceptions(IBaseClass obj, int CustomerId)
{
Log(obj.Exceptions);
Log(obj.Input);
}
If they don't inherit from a common interface, then I suggest they should.
You cannot pass Type parameter to Log method. You have to pass an instance of Type parameter.
try following:
private void LogExceptions<T1, T2>(T1 input, T2 exceptions, int customerId)
{
Log(input);
Log(exceptions);
}
What I feel is if there are 4 methods and they don't have same method signature its completely fine, it doesn't always have to be generic it has to be readable as well.
Why would you make 4 calls Log(T1),Log(T2),Log(T3),Log(T4) if all you have to do is Log(OneofTheTypeWhichYouKnowWhenCallingTheMethod).
Having said that you can always have reflection to play around like in your case.
I am creating a C# library with some reusable code and was trying to create a method inside a method. I have a method like this:
public static void Method1()
{
// Code
}
What I would like to do is this:
public static void Method1()
{
public static void Method2()
{
}
public static void Method3()
{
}
}
Then I could choose either Method1.Method2 or Method1.Method3. Obviously the compiler isn't happy about this, any help is much appreciated. Thanks.
If by nested method, you mean a method that is only callable within that method (like in Delphi) you could use delegates.
public static void Method1()
{
var method2 = new Action(() => { /* action body */ } );
var method3 = new Action(() => { /* action body */ } );
//call them like normal methods
method2();
method3();
//if you want an argument
var actionWithArgument = new Action<int>(i => { Console.WriteLine(i); });
actionWithArgument(5);
//if you want to return something
var function = new Func<int, int>(i => { return i++; });
int test = function(6);
}
Yes, when C# 7.0 is released, Local Functions will allow you to do that. You will be able to have a method, inside a method as:
public int GetName(int userId)
{
int GetFamilyName(int id)
{
return User.FamilyName;
}
string firstName = User.FirstName;
var fullName = firstName + GetFamilyName(userId);
return fullName;
}
Note that public (and similar modifiers) are not supported C# programming guide:
Because all local functions are private, including an access modifier, such as the private keyword, generates compiler error CS0106, "
This answer was written before C# 7 came out. With C# 7 you can write local methods.
No, you can't do that. You could create a nested class:
public class ContainingClass
{
public static class NestedClass
{
public static void Method2()
{
}
public static void Method3()
{
}
}
}
You'd then call:
ContainingClass.NestedClass.Method2();
or
ContainingClass.NestedClass.Method3();
I wouldn't recommend this though. Usually it's a bad idea to have public nested types.
Can you tell us more about what you're trying to achieve? There may well be a better approach.
You can define delegates within your method with complete code and call them if you want.
public class MyMethods
{
public void Method1()
{
// defining your methods
Action method1 = new Action( () =>
{
Console.WriteLine("I am method 1");
Thread.Sleep(100);
var b = 3.14;
Console.WriteLine(b);
}
);
Action<int> method2 = new Action<int>( a =>
{
Console.WriteLine("I am method 2");
Console.WriteLine(a);
}
);
Func<int, bool> method3 = new Func<int, bool>( a =>
{
Console.WriteLine("I am a function");
return a > 10;
}
);
// calling your methods
method1.Invoke();
method2.Invoke(10);
method3.Invoke(5);
}
}
There is always an alternative of using a nested class within a class that will not be visible from outside and calling its methods, like:
public class SuperClass
{
internal static class HelperClass
{
internal static void Method2() {}
}
public void Method1 ()
{
HelperClass.Method2();
}
}
As of C# 7.0 you can do that:
public static void SlimShady()
{
void Hi([CallerMemberName] string name = null)
{
Console.WriteLine($"Hi! My name is {name}");
}
Hi();
}
This is called local functions, that is just what you were looking for.
I took the example from here, but further informatin can be found here and here.
Why you don't use classes?
public static class Helper
{
public static string MethodA()
{
return "A";
}
public static string MethodA()
{
return "A";
}
}
Now you can acces MethodA via
Helper.MethodA();
Older thread, but C# does have the concept of nested functions
Func<int> getCalcFunction(int total, bool useAddition)
{
int overallValue = 0;
if (useAddition)
{
Func<int> incrementer = new Func<int>(() =>
{
overallValue += total;
return overallValue;
});
return incrementer;
}
else
{
Func<int> decrementer = new Func<int>(() =>
{
overallValue -= total;
return overallValue;
});
return decrementer;
}
}
private void CalcTotals()
{
Func<int> decrem = getCalcFunction(30, false);
int a = decrem(); //result = -30
a = decrem(); //result = -60
Func<int> increm = getCalcFunction(30, true);
int b = increm(); //result = 30
b = increm(); //result = 60
}
Your nearly there
public static void Method1()
should be
public static class Method1{}
Don't you want to use nested class instead?
That's said, you seem to not respect the Single Responsibility Principle because you want a single method do more than one thing at a time.
Why don't you just Run a method within another
public void M1()
{
DO STUFF
}
public void M1()
{
DO STUFF
M1();
}