How to cascade optional parameter? - c#

I have a worker method with an optional parameter
Work(string input = DefaultInput)
{
//do stuff
}
And I have a wrapper around this, which also take the string input, but this can also be optional...
WorkWrapper(int someParameter, string input = DefaultInput)
{
//do initialization
Work(input);
}
The problem here is I duplicate reference to DefaultInput, if, say, I change the default input of work to NewDefaultInput, I will need to update the workWrapper as well, otherwise it will still use the old default.
Is there a way so that the default input do not need to be declared twice? Possibly without having two overloads for workwrapper..

If you want the defaults to be in sync between the two methods, you really don't need the default in the wrapper, right?
public void Work(string input = DefaultInput)
{
//do stuff
}
…
public void WorkWrapper(int someParameter, string inputOverride = null)
{
//do initialization
if (inputOverride == null) Work();
else Work(inputOverride);
}
If they are in the same class/hierarchy, you could also just declare a const to ensure that the defaults remain the same.
private const string DEFAULT_INPUT = "Default Input"; // protected if in base class
public void Work(string input = DEFAULT_INPUT)
{
//do stuff
}
public void WorkWrapper(int someParameter, string input = DEFAULT_INPUT)
{
//do initialization
Work(input);
}

Related

Convert string containing bool condition to bool (C#)

I would like to convert (but i think it's not possible) a string into a bool, in this way:
string a = "b.Contains('!')";
private void print(string condition)
{
string b = "Have a nice day!";
/* Some kind of conversion here for condition parameter */
/* like bool.Parse(condition) or Bool.Convert(condition) */
if(condition)
{
Console.Write("String contains !-character.");
}
}
Mind that the bool-string has to be passed to the function as a parameter.
Is there a way to achieve this?
There is no built in way to parse your string to a expression.
But of your goal is to sent the expression to an other function you could do this
using System;
public class Program
{
public static void Main()
{
print(x=>x.Contains("!"));
}
private static void print(Func<string,bool> condition)
{
string b = "Have a nice day!";
/* Some kind of conversion here for condition parameter */
/* like bool.Parse(condition) or Bool.Convert(condition) */
if(condition.Invoke(b))
{
Console.Write("String contains !-character.");
}
}
}
if you would like a non build in way you could look at : Is there a tool for parsing a string to create a C# func?
I think you need to use an auxiliar bool variable, like this example..
bool aux = false;
private bool print(string condition)
{
string b = "Have a nice day!";
if(b.Contains(condition))
aux = true;
return aux;
}
Or the same example without auxiliar.
private bool print(string condition)
{
string b = "Have a nice day!";
return b.Contains(condition);
}
Then call the method print to check if it is true or false and write the message you want
if(print("!"))
Console.WriteLine("String contains !-character.");

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;
}
}

Implementing a safe access container

Assume I have some class that represents a container. That container holds some public properties with get and set modifiers.
What I want is to implement some mechanism that will enable access and disable access to these properties reference at runtime.
For example, when some boolean flag is true, you can access these properties. That means that:
SomeClass.Property1;
Will not generate an exception and will return the object.
However, when it is false, the above line of code will throw an exception.
It is of course possible to be done when using some boolean key, and checking it at the gateway to every property.
My question is, is it possible to implement such mechanism that will enfoce these limitations for all the properties in the class, without the need to assert these conditions within every access to these properties.
Thanks for helping.
It looks like null object pattern might helps.
Simple code that shows how it can be used in your case. Not exactly the same as you want but it doesn't need to assert conditions with every access to object's properties and methods.
Entities:
abstract class AbstractEntity
{
public abstract void DoSomething();
public abstract void DoSomethingElse();
public abstract int Property { get; set; }
}
class RealEntity : AbstractEntity
{
public override void DoSomething()
{
Console.WriteLine("Something");
}
public override void DoSomethingElse()
{
Console.WriteLine("Something else");
}
public override int Property { get; set; }
}
class NullEntity : AbstractEntity
{
public override void DoSomething()
{
// do nothing or throw exception
}
public override void DoSomethingElse()
{
// do nothing or throw exception
}
public override int Property
{
get { throw new Exception(); }
set { throw new Exception(); }
}
}
Simple example of AccessContainer:
class AccessContainer
{
private RealEntity _entity = new RealEntity();
private NullEntity _nullEntity = new NullEntity();
private bool _access = true;
public AbstractEntity Entity
{
get => _access ? (AbstractEntity) _entity : (AbstractEntity) _nullEntity;
}
public void OpenAccess()
{
_access = true;
}
public void DenyAccess()
{
_access = false;
}
}
Usage:
var container = new AccessContainer();
container.Entity.DoSomething(); // prints something
var prop = container.Entity.Property; // access to property
container.DenyAccess();
container.Entity.DoSomething(); // do nothing
container.OpenAccess();
container.Entity.DoSomething(); // prints something again
container.DenyAccess();
var prop2 = container.Entity.Property; // exception
What you are asking for doesn't natively exist, you're going to have to write some sort of wrapping functionality to test whether accessibility is granted.
public interface IAccessOwner {
bool Accessible { get; }
}
[DebuggerDisplay("Accessible: {Accessible,nq} - Value: {ToString()}")]
[DebuggerTypeProxy(typeof(RestrictedObject<>.DebuggerProxy))]
public class RestrictedObject<T> {
private readonly IAccessOwner _owner;
private T _value;
public RestrictedObject(IAccessOwner owner, T initialValue)
: this(owner) {
_value = initialValue;
}
public RestrictedObject(IAccessOwner owner) {
_owner = owner ?? throw new ArgumentNullException(nameof(owner));
}
public T Value {
get {
ThrowIfInaccessible();
return _value;
}
set {
ThrowIfInaccessible();
_value = value;
}
}
public bool Accessible => _owner.Accessible;
public override string ToString() {
if (!Accessible)
return "<Inaccessible>"; // ToString should never throw
if (_value is { } val)
return val.ToString();
return "<null>";
}
private void ThrowIfInaccessible() {
if(!Accessible)
throw new InvalidOperationException("Not accessible!");
}
// explicit operator to cast directly to value
public static explicit operator T(RestrictedObject<T> ro) {
ro.ThrowIfInaccessible();
return ro.Value;
}
private sealed class DebuggerProxy {
public bool Accessible { get; }
public T Value { get; }
public DebuggerProxy(RestrictedObject<T> ro) {
bool acc = Accessible = ro.Accessible;
if (acc)
Value = ro._value;
}
}
}
You can then use properties of this type in your class:
public class MyClass : IAccessOwner {
private readonly RestrictedObject<int> _prop1;
private readonly RestrictedObject<string> _prop2;
public MyClass(int someVal) {
_prop1 = new RestrictedObject<int>(this, someVal);
_prop2 = new RestrictedObject<string>(this);
Accessible = true;
}
public bool Accessible { get; private set; }
// you determine how you want to toggle the above property.
// Exposing it publicly defeats the purpose of all of this,
// but for demo purposes only:
public void DenyAccess() {
Accessible = false;
}
public void AllowAccess() {
Accessible = true;
}
// these properties will throw exceptions if the owner
// (this object) is not currently accessible.
public int Prop1 {
get => _prop1.Value;
set => _prop1.Value = value;
}
public string Prop2 {
get => _prop2.Value;
set => _prop2.Value = value;
}
// alternatively return the wrapper itself
// allowing you to control the accessibility
// even after returning the object
public RestrictedObject<string> AltProp2 => _prop2;
}
You would then use it like the following (obviously exceptions will halt the execution, handling has been elided):
var mc = new MyClass(3);
Console.WriteLine(mc.Prop1); // prints 3
Console.WriteLine(mc.Prop2); // prints null
var temp = mc.AltProp2; // use the wrapper directly
mc.Prop2 = "Hello";
Console.WriteLine(mc.Prop2); // prints Hello
Console.WriteLine(temp.Value); // prints Hello
Console.WriteLine((string)temp); // explicit operator, prints Hello
mc.DenyAccess();
mc.Prop1 = 33; // throws!
Console.WriteLine(mc.Prop1); // throws!
Console.WriteLine(mc.Prop2); // throws!
Console.WriteLine(temp.Value); // throws!
Console.WriteLine((string)temp); // explicit operator, throws!
Console.WriteLine(temp); // prints "<Inaccessible>"
mc.AllowAccess();
string temp3 = (string)temp; // "Hello", explicit operator works again
mc.Prop1 = 22; // as do our setters
mc.Prop2 = "Goodbye";
if (temp.Accessible) {
Console.WriteLine(temp); // "Goodbye"
}
The only thing that won't throw an exception is the override of ToString on the RestrictedObject type itself since you should never throw from ToString. Instead we just return <Inaccessible>.
We've also changed how the RestrictedObject<T> is displayed in a debugger via the DebuggerTypeProxyAttribute. If someone tries to inspect the object's properties they will see the Accessible property and only if true will the wrapped object's Value appear. Otherwise, default(T) will be displayed (null for reference types, 0 for integral types and false for bool). Furthermore, through use of the DebuggerDisplayAttribute we've customized the display of the collapsed version of our object such that it shows the Accessible property alongside our customized ToString.
Note that this still has the drawback that if someone retrieves the inner/wrapped object and accessibility has later been denied, they still have the object. There's nothing you are going to be able to do to really guard against that case. You must also realize (and accept) that anyone using reflection could alter or access the state of the object if they really wanted to.
I will also note that this violates normal C# practices, which typically dictate that properties should not throw exceptions. Microsoft's own guidelines say as much, though they use the term "Avoid" rather than "Do Not". The framework itself is guilty of violating this "rule". If you're going to violate the principle of least surprise, at the very least have the courtesy to document this behavior for consumers of your API.

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