Add methods to Func - c#

I have a list of Func and I want to add elements.
If I add them on Start like below, no problem:
public List<System.Func<bool>> conditions = new List<System.Func<bool>>();
void Start()
{
conditions.Add(Iamdead);
conditions.Add(Iamalive);
}
bool Iamdead()
{
...
return ...;
}
bool Iamalive()
{
...
return ...;
}
But I want to define the list without Start so that I have a clean list of methods that I can see as elements in a row. I have tried the classic format:
public List<System.Func<bool>> conditions = new List<System.Func<bool>>()
{
bool Iamdead()
{
...
return ...;
}
,
bool Iamalive()
{
...
return ...;
}
};
This gave me parsing error
I tried like that:
public List<System.Func<bool>> conditions = new List<System.Func<bool>>()
{
Iamdead,Iamalive
};
static bool Iamdead()
{
...
return ...;
}
static bool Iamalive()
{
...
return ...;
}
This worked only if the methods are static but I do not want them to be static. Without static, it doesn't work. It seems I couldn't understand the data structure here. Can anyone tell me the correct way of defining Func in a list?
Thanks

I strongly suspect the problem is that you're trying to access this (implicitly) within a field initializer. You're not allowed to do that. Just move the initialization into a constructor:
// You don't really use public fields, do you?
private readonly List<Func<bool>> conditions;
public MyClass()
{
conditions = new List<Func<bool>> { Method1, Method2 };
}
private bool Method1() { ... }
private bool Method2() { ... }
(I'm assuming you actually want your conditions to depend on state within the instance. If they don't, you don't need this. If the methods aren't used other than for these conditions, and they're short enough, you might want to use lambda expressions instead.)

Like so:
public List<System.Func<bool>> conditions = new List<System.Func<bool>>()
{
() => false,
() => true,
};

You can just use lambdas:
public List<System.Func<bool>> conditions = new List<System.Func<bool>>()
{
() =>
{
return false;
}
,
() =>
{
return true;
}
};

Related

How to return a named tuple with only one field

I wrote a function in c# which initially returned a named tuple.
But now, I only need one field of this tuple and I would like to keep the name because it helps me to understand my code.
private static (bool informationAboutTheExecution, bool field2thatIdontNeedAnymore) doSomething() {
// do something
return (true, false);
}
This function compile. But It's the following function that I want
private static (bool informationAboutTheExecution) doSomething() {
// do something
return (true);
}
the error messages:
Tuple must containt at least two elements
cannot implcitly convvert type 'bool' to '(informationAboutTheExecution,?)
Has somebody a solution to keep the name of the returned value?
I just want to add another option, althought he out is the easiest workaround and Marc explained already why it's not possible. I would simply create a class for it:
public class ExecutionResult
{
public bool InformationAboutTheExecution { get; set; }
}
private static ExecutionResult DoSomething()
{
// do something
return new ExecutionResult{ InformationAboutTheExecution = true };
}
The class can be extended easily and you could also ensure that it's never null and can be created with factory methods like these for example:
public class SuccessfulExecution: ExecutionResult
{
public static ExecutionResult Create() => new ExecutionResult{ InformationAboutTheExecution = true };
}
public class FailedExecution : ExecutionResult
{
public static ExecutionResult Create() => new ExecutionResult { InformationAboutTheExecution = false };
}
Now you can write code like this:
private static ExecutionResult DoSomething()
{
// do something
return SuccessfulExecution.Create();
}
and in case of an error(for example) you can add a ErrorMesage property:
private static ExecutionResult DoSomething()
{
try
{
// do something
return SuccessfulExecution.Create();
}
catch(Exception ex)
{
// build your error-message here and log it also
return FailedExecution.Create(errorMessage);
}
}
You cannot, basically. You can return a ValueTuple<bool>, but that doesn't have names. You can't add [return:TupleElementNamesAttribute] manually, as the compiler explicitly does not let you (CS8138). You could just return bool. You can do the following, but it isn't any more helpful than just returning bool:
private static ValueTuple<bool> doSomething()
=> new ValueTuple<bool>(true);
Part of the problem is that ({some expression}) is already a valid expression before value-tuple syntax was introduced, which is why
private static ValueTuple<bool> doSomething()
=> (true);
is not allowed.
If you must name your return, you can do this:
private static void doSomething(out bool information) {
// do something
information = true;
}
then call it with
bool result;
doSomething(out result);

Is it possible to have method only accessible after certain conditions are met?

I'm trying to make a method, MethodA, only accessible when bool, executable, is true. Otherwise an other method, MethodB, is accessible. For example:
private bool executable = true;
public int MethodA(); <-- // Is accessible from outside of the class because executable is true
public string MethodB() <-- // Is not accessible because executable is true
The main reason I'm trying to do this is because the 2 methods return 2 different types. So my question is, is this even possible?
Option #1
You may be able to get what you want using Polymorphism and Generics. This would also allow you to add additional method strategies if needed.
public interface IMethodStrategy<out T>
{
T DoSomething();
}
public class MethodOneStrategy : IMethodStrategy<string>
{
public string DoSomething()
{
return "This strategy returns a string";
}
}
public class MethodTwoStrategy : IMethodStrategy<int>
{
public int DoSomething()
{
return 100; // this strategy returns an int
}
}
// And you would use it like so...
static void Main(string[] args)
{
bool executable = true;
object result = null;
if (executable)
{
MethodOneStrategy methodA = new MethodOneStrategy();
result = methodA.DoSomething();
}
else
{
MethodTwoStrategy methodB = new MethodTwoStrategy();
result = methodB.DoSomething();
}
}
Option #2
Another option could be a simple proxy method to wrap the worker methods.
// proxy class to wrap actual method call with proxy call
public class MethodProxy
{
public object DoMethodWork(bool executable)
{
if (executable)
{
return MethodA();
}
else
{
return MethodB();
}
}
private int MethodA()
{
return 100; // returns int type
}
private string MethodB()
{
return "this method returns a string";
}
}
// used like so
static void Main(string[] args)
{
var methodProxy = new MethodProxy();
object result = methodProxy.DoMethodWork(true);
}
Use conditional compilation for this.
#if RELEASE
public string MethodB() ...
#endif
Although I have my doubts about whether you need this or not. Your rationale doesn't make much sense.
You can use different Build Configurations to manage your conditional compile symbols.
if(executable)
MethodA();
else
MethodB();
OR
if(executable)
MethodA();
MethodB();
not entirely sure what you are trying to do but this could be one way, probably not the most efficient way but could work depending on what you are trying to do?
public int MethodA(executable)
{
if(executable = true)
{
//do stuff
}
else
{
return -1;
}
}
public String MethodB(executable)
{
if(executable = false)
{
//do stuff
}
else
{
String error = "MethodB cannot be used right now";
return error;
}
}

Creating a custom property class for multiple re-use within a class

Suppose I have a C# class that has multiple properties that all look like this:
private bool _var1Dirty = true;
private Double? _var1;
public Double? Var1
{
get
{
if (_var1Dirty)
{
_var1 = Method_Var1();
_var1Dirty = false;
}
return _var1;
}
}
And the only differences between each of these properties would be:
The type of return var (in this case Double?, but could just as easily be int, string, etc)
The method call - Method_Var1() (Each property would have a different one)
Is there any way I could write this as a custom class?
Something along the lines of:
public class Prop
{
public delegate T Func();
private bool _dirty = true;
private T _val;
public T Val
{
get
{
if (_dirty)
{
_val = Func;
_dirty = false;
}
return _val;
}
}
}
And then I could pass into it the:
Return type T
Method Func
(PS - I know this won't compile / is dead wrong, but I wanted to give an idea of what I'm looking for)
Any help / guidance would be really appreciated.
Thanks!!!
You're close. You can do something along the lines of this:
public class Dirty<T>
{
public Dirty(Func<T> valueFactory)
{
this.valueFactory = valueFactory;
dirty = true;
}
private Func<T> valueFactory;
private bool dirty;
private T value;
public T Value
{
get
{
if (dirty)
{
value = valueFactory();
dirty = false;
}
return value;
}
}
}
And you consume it like this:
Dirty<double?> dirtyDouble = new Dirty<double?>(() => SomethingThatReturnsADouble());
double? value = dirtyDouble.Value;
I'm not sure what the dirty checking actually does, but if you need someone more complicated than a bool you can always turn it into some Func<T> the checks for dirtiness.
Edit:
Given #mikez comment and your answer, you can save yourself the creation of the Dirty<T> class by using the built in Lazy<T>, which also guarantess thread safety:
public class F
{
private Lazy<double?> lazyDouble = new Lazy<double?>(() =>
MethodThatReturnsNullableDouble(), true);
public double? Value
{
get
{
return lazyDouble.Value;
}
}
}

How to implement code like SomeObject.SomeFunction().SomeOtherFunction();

Today, I searched a line of code which was written like:
SomeObject.SomeFunction().SomeOtherFunction();
I am unable to understand this. I tried to search it on Google about this but no luck.
Please help me to understand this.
SomeObject has a function called SomeFunction(). This function returns an object (of an unknown type for us, based on your example). This object has a function called SomeOtherFunction().
The question "how to implement" is a bit vague to answer, though.
Consider the following
public class FirstClass
{
public SecondClass SomeFunction()
{
return new SecondClass();
}
}
public class SecondClass
{
public void SomeOtherFunction()
{
}
}
So the following are equivalent.
FirstClass SomeObject = new FirstClass();
SomeObject.SomeFuntion().SomeOtherFunction();
OR
FirstClass SomeObject = new FirstClass();
SecondClass two = SomeObject.SomeFuntion();
two.SomeOtherFunction();
This is called Fluent coding or method chaining and is a method of programming that allows you to chain commands together. It is very common in LINQ where you might have something like this:
var result = myList.Where(x => x.ID > 5).GroupBy(x => x.Name).Sort().ToList();
This would give you all the records greater than 5, then grouped by name, sorted and returned as a list. The same code could be written in long hand like this:
var result = myList.Where(x => x.ID > 5);
result = result.GroupBy(x => x.Name);
result = result.Sort();
result = result.ToList();
But you can see this is much more long winded.
This style of programming called FluentInterface style.
Eg:
internal class FluentStyle
{
public FluentStyle ConnectToDb()
{
// some logic
return this;
}
public FluentStyle FetchData()
{
// some logic
return this;
}
public FluentStyle BindData()
{
// some logic
return this;
}
public FluentStyle RefreshData()
{
// some logic
return this;
}
}
And the object can be created and method can be consumed as below;
var fluentStyle = new FluentStyle();
fluentStyle.ConnectToDb().FetchData().BindData().RefreshData();
This type of chaining may involve extension methods. These allow addition of new methods to existing classes (even those that you don't have the source code for).
e.g.
public static class StringExtender
{
public static string MyMethod1(this string Input)
{
return ...
}
public static string MyMethod2(this string Input)
{
return ...
}
}
....
public string AString = "some string";
public string NewString = AString.MyMethod1().MyMethod2();
This can be done using extension methods
public class FirstClass
{
}
public class SecondClass
{
}
public class ThridClass
{
}
public static class Extensions
{
public static SecondClass GetSecondClass(this FirstClass f)
{
return new SecondClass();
}
public static ThridClass GetThridClass(this SecondClass s)
{
return new ThridClass();
}
}
}
AND then you can ues
FirstClass f= new FirstClass();
f.GetSecondClass().GetThridClass();

Can I conditionally control method calls at runtime with attributes?

The Conditional Attribute in .NET allows you to disable the invocation of methods at compile time. I am looking for basically the same exact thing, but at run time. I feel like something like this should exist in AOP frameworks, but I don't know the name so I am having trouble figuring out if it is supported.
So as an example I'd like to do something like this
[RuntimeConditional("Bob")]
public static void M() {
Console.WriteLine("Executed Class1.M");
}
//.....
//Determines if a method should execute.
public bool RuntimeConditional(string[] conditions) {
bool shouldExecute = conditions[0] == "Bob";
return shouldExecute;
}
So where ever in code there is a call to the M method, it would first call RuntimeConditional and pass in Bob to determine if M should be executed.
You can actually use PostSharp to do what you want.
Here's a simple example you can use:
[Serializable]
public class RuntimeConditional : OnMethodInvocationAspect
{
private string[] _conditions;
public RuntimeConditional(params string[] conditions)
{
_conditions = conditions;
}
public override void OnInvocation(MethodInvocationEventArgs eventArgs)
{
if (_conditions[0] == "Bob") // do whatever check you want here
{
eventArgs.Proceed();
}
}
}
Or, since you're just looking at "before" the method executes, you can use the OnMethodBoundaryAspect:
[Serializable]
public class RuntimeConditional : OnMethodBoundaryAspect
{
private string[] _conditions;
public RuntimeConditional(params string[] conditions)
{
_conditions = conditions;
}
public override void OnEntry(MethodExecutionEventArgs eventArgs)
{
if (_conditions[0] != "Bob")
{
eventArgs.FlowBehavior = FlowBehavior.Return; // return immediately without executing
}
}
}
If your methods have return values, you can deal with them too. eventArgs has a returnValue property that is settable.
I believe this would be a very simple way of doing what you described:
public static void M()
{
if (RuntimeConditional("Bob"))
{
Console.WriteLine("Executed Class1.M");
}
}
Thanks

Categories

Resources