Scope of string inside lambda - c#

I have an interesting scenario in which I've built a validation checking system that maintains a series of requirements in the form List<Tuple<Func<bool>, string>> where the Func should return true if validation failed and false otherwise. The string is a corresponding rejection description that describes the condition should the test fail.
In more simple tests like the following the validation system is quite simple:
validationChecks.Add(Tuple.Create<Func<bool>, string>(() =>
value1 == requiredValue, "value 1 did not have the required value"));
I'm struggling to understand the scope of variables within the lambda for the Func in a more advanced scenario in which the rejection string is calculated in a call to another part of the system. The scenario looks something like this:
string rejectionString = null;
validationChecks.Add(Tuple.Create<Func<bool>, string>(() => {
rejectionString = CallToAnotherMethodThatReturnsString(parameter);
if (rejectionString != null) {
return true;
} else {
return false;
}
}, rejectionString));
EDIT: As observed through testing, when this check fails the rejectionString from the Tuple is still null. I want the rejectionString that was generated by the CallToAnotherMethod to be used instead, is there any way I can do this using ref or otherwise? I need the Func's code to be able to affect the value of the string inside Item2 of the Tuple.
The problem is that the code inside of CallToAnotherMethodThatReturnsString might be code that I only want executed ONCE. However should the check fail I want to use the string that would have been returned from it as my rejection description in the Tuple. I'm unable to tell at this point what the effect of my use of rejectionString in this second example will accomplish? Will rejectionString inside the Tuple always be null? Or if CallToAnotherMethodThatReturnsString returns a different value will it be updated?

Just an idea that might work. I think if you change your second Tuple parameter to a Func that returns string instead of string value, you could come close to what you need.
string rejectionString = null;
validationChecks.Add(Tuple.Create<Func<bool>, Func<string>>(() =>
{
rejectionString = CallToAnotherMethodThatReturnsString(parameter);
if (rejectionString != null) {
return true;
} else {return false;}
},
()=>rejectionString));
In the first case your validation check would be set as
validationChecks.Add(Tuple.Create<Func<bool>, Func<string>>(() => value1 == requiredValue, ()=>"value 1 did not have the required value"));
And your validation is logic is then
if(validationChecks[0].Item1()==false)
var error = validationChecks[0].Item2();

Related

EWS comparing ItemIDs shows no match but ItemID.ToString comparison shows a match.

I am using EWS to find items. I expect the result set to be larger than the page size so I have implemented a check to ensure my result set doesn't change while paging. The code is pretty much the same as recommended by Microsoft at the link below.
How to: Perform paged searches by using EWS in Exchange
Here is the relevant code snippet:
if (results.Items.First<Item>().Id != anchorId)
{
Console.Writeline("The collection has changed while paging. " +
"Some results may be missed.");
}
The problem is, the first ItemID and the acnchorID never match even though I am sure the collection is not changing. Further to this, if I convert the IDs to strings and do a string comparison as below, they always match.
string a = results.Items.First<Item>().Id.ToString();
string b = anchorId.ToString();
bool result = a.Equals(b, StringComparison.Ordinal);
Debug.Print("Ordinal comparison: {0}",result ? "equal." : "not equal.");
I have tried running the code on different result sets and with different page sizes and the outcome is always the same: the ItemIds never match but the ID strings always match.
Question
I am reluctant to drop the approach recommended by Microsoft in favor of a string comparison approach especially as I can't explain why the FolderID comparison approach isn't working. But, on the other hand, I can't explain why the string comparison always works. Does anyone have any thoughts on why I might be seeing these strange and conflicting results.
What i sucpect is happening in this line:
if (results.Items.First<Item>().Id != anchorId)
Seeing that the ItemId object, or its parents, do not override the != operator. The object references of the ItemId are being compared. And this should always return true because we create a different object for each ItemId.
But the toString() method is being overriden by this :
public override string ToString()
{
return (this.uniqueId == null) ? string.Empty : this.uniqueId;
}
Which explains why comparing this results in a good comparison of the keys.
The best way to handle this i think is to use the equals method of the ItemId class which has its own implementation:
public override bool Equals(object obj)
{
if (object.ReferenceEquals(this, obj))
{
return true;
}
else
{
ServiceId other = obj as ServiceId;
if (other == null)
{
return false;
}
else if (!(this.IsValid && other.IsValid))
{
return false;
}
else
{
return this.UniqueId.Equals(other.UniqueId);
}
}
}
So conclusion use this for the comparison of the keys:
if (!results.Items.First<Item>().Id.Equals(anchorId))
{
Console.Writeline("The collection has changed while paging. " +
"Some results may be missed.");
}
And if u are interested u can visit the github page for the source code: https://github.com/OfficeDev/ews-managed-api

How to test if method returns expected data type?

Is it possible to create a NUnit Test method to check if the method returns the expected data type ?
Here's what I mean:
I've a static string that takes two parameters and checks to see if it matches with another string. If it does the methods simply returns that string.
I want to test to ensure that this method does infact return type of string and any exceptions that might occur.
Sample Code:
public static string GetXmlAttributeValue(this XmlElement element, string attributeName)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
if (attributeName == null)
{
throw new ArgumentNullException("attributeName");
}
string attributeValue = string.Empty;
if (element.HasAttribute(attributeName))
attributeValue = element.Attributes[attributeName].Value;
else
throw new XmlException(element.LocalName + " does not have an attribute called " + attributeName);
return attributeValue;
}
Here's how my solution is looking:
I'd like to write my test code within the TestLibrary class library.
Normally, there is no need to test the return type. C# is statically typed language, so this method cannot return something else different than string.
But If you want to write a test, which will fail if someone changes the return type, you can do something like this:
Assert.That(result, Is.TypeOf<string>());
To test for the return type you can use the Is.TypeOf<yourType> syntax mentioned by #dimitar-tsonev. Here is a list of the supported type contraints:
You also mention that you want to write tests to verify the exceptions. For that you can either use the ExpectedExceptionAttribute attribute as documented here or the exception asserts syntax as documented here.
You Don't Need To Test For the method to return a certain data type because it can only return the specific return type. You could run the method and use an Assert to check it isn't null, then you know the method has returned the correct type.
var result = GetXmlAttributeValue(par1,par2);
Assert.isNotNull(result);
Hope This helps!

Convert loop to Maybe monad

Recently I tried applying Maybe monad pattern in my C# code using this library.
What I found difficult to grasp was converting such a function into Maybe paradigm:
public Maybe<object> DoSomething(IReader reader)
{
while (true)
{
var result = reader.Read();
if (result == null) return Maybe<object>.Nothing;
if (result.HasValue) return new Maybe<object>(null);
}
}
I would like to have it written using from x in X form. The functionality that stands behind this function is to read IReader until it returns a value (Maybe has a value) or an error occurs (null gets returned).
the answer to your comment/question is: you don't - yeah you could try it using recursive calls but this might fail horrible in C# and you are way better of with the while
from x in X is just the monadic - bind (it get's translated into the SelectMany functions) and there is just no direct way in the LINQ syntax for this.
But you can write your own function like this:
public tValue DoUntilSome<tValue>(Func<Maybe<tValue>> f)
{
while (true)
{
var x = f();
if (x.HasValue) return x.Value;
}
}
and call like (see below)
var result = DoUntilSome(() => TryRead(reader));
remarks
first the Maybe<object> (object) part is a smell - because you most certainly want a concrete type in there instead of the generic object
Then new Maybe<object>(null) is very strange too
I would have suggested something like:
public Maybe<tValue> TryRead<tValue>(IReader reader)
{
var result = reader.Read();
if (result == null || !result.HasValue)
return Maybe<tValue>.Nothing;
return new Maybe<tValue>((tValue)reader.Value);
}
then of course this part is there to get some Maybe value - the thing you are trying to do with from x in X is the monadic-bind - which you can only use once you have a Maybe to start with:
from value in TryRead<tValue>(reader)
from other in TrySomethingDifferent(value) // here is the bind
select ....
disclaimer
I did not compile any of this (because I was to lazy to download the github project and stuff) - put you should be able to easily solve any syntax errors that might hide there - sorry for that
In case you have major troubles just leave a comment

How To write a generic class/method in C# 2.0 to return a List of objects or just a simple string based on a condition?

I have a webservice which has a method that returns a List of Payment objects provided with some input parameters. However if the input parameters are not in the correct format, I would like to return an error message which is of type string, not a List of Payment objects. I would like do this using Generic Classes concept in C#. Anyone has any idea about how I can manage to do this ?
Many thanks,
Here is some code:
[WebMethod]
public List<Payment> GetPayments(string firstDate, string lastDate, string entegrationStatus)
{
if (Common.IsDateTime(firstDate) && Common.IsDateTime(firstDate) && Common.IsValidEntegrationStatus(entegrationStatus))
{
return paymentManager.GetPayments(firstDate, lastDate, entegrationStatus);
}
else
{
return "ERROR MESSAGE";
}
}
I'm fairly sure all you need to do is throw an exception in your service method. This will populate the Error property of the async event args that are returned back to the client. The client can check for errors in its 'async completed' event handler using this property and handle it accordingly.
This is probably a better design than just sending back a string as well because it separates a regular return message from an error return message.
It's as simple as:
Edit - Using the code you posted:
[WebMethod]
public List<Payment> GetPayments(string firstDate, string lastDate, string entegrationStatus)
{
if (Common.IsDateTime(firstDate) && Common.IsDateTime(firstDate) && Common.IsValidEntegrationStatus(entegrationStatus))
{
return paymentManager.GetPayments(firstDate, lastDate, entegrationStatus);
}
else
{
throw new ArgumentException("Your error message.");
}
}
If you REALLY want to do it, you can use a Tuple-like class (they introduced Tuples in C# 4.0). If you are using C# 2.0 then you can use KeyValuePair<List<YourObject>, string>. Be aware that I'm NOT suggesting you do it! You should throw an exception, or put the string message as an out parameter.
well you could do something simply like having an ErrorString property on your object, and if your main method fails, set the ErrorString and return null from your method
SomeObject o = new SomeOject();
ILIst<Things> things = o.GetThings();
if(things == null)
Response.Write(o.ErrorString)
A generic isn't really suitable for this use, because you cannot return a generic type based on a runtime condition within a generic method (since the method must be compiled with an exact type to run in the first place).
A common approach is to use an out parameter for your list and your string, and have your method return a bool denoting whether the list was returned. These methods are usually prefixed with Try.... eg
bool TryGetList<T>(out IList<T> lst, out string Error) {
if (!somcondition) {
Error = "err!";
return false;
}
lst = ...
return true;
}
The other technique is simply to use exceptions, but they can be more costly if you are likely to have errors frequently. An ArgumentException for example will let you specify which argument was invalid, and the caller can check the ParamName of the caught exception to decide what he should do afterwards.

Refactor help c#

I have several hundred lines of code like this:
if (c.SomeValue == null || c.SomeProperty.Status != 'Y')
{
btnRecordCall.Enabled = false;
}
if (c.SomeValue == null || (c.SomeProperty.Status != 'Y' &&
c.SomeOtherPropertyAction != 'Y'))
{
btnAddAction.Enabled = false;
}
if (c.SomeValue == null || c.SomeProperty.Processing != 'Y')
{
btnProcesss.Enabled = false;
}
How can I refactor this correctly? I see that the check 'c.SomeValue == null' is being called every time, but it is included with other criteria. How can I possibly eliminate this duplicate code?
I would use the specification pattern, and build composite specifications that map to a proper Enabled value.
The overall question you want to answer is whether some object c satisfies a given condition, which then allows you to decide if you want something enabled. So then you have this interface:
interface ICriteria<T>
{
bool IsSatisfiedBy(T c);
}
Then your code will look like this:
ICriteria<SomeClass> cr = GetCriteria();
btnAddAction.Enabled = cr.IsSatisfiedBy(c);
The next step is to compose a suitable ICriteria object. You can have another ICriteria implementation, (in additon to Or and And), called PredicateCriteria which looks like this:
class PredicateCriteria<T> : ICriteria<T>
{
public PredicateCriteria(Func<T, bool> p) {
this.predicate = p;
}
readonly Func<T, bool> predicate;
public bool IsSatisfiedBy(T item) {
return this.predicate(item);
}
}
One instance of this would be:
var c = new PredicateCriteria<SomeClass>(c => c.SomeValue != null);
The rest would be composition of this with other criteria.
If you don't want to do much refactoring, you can easily pull the null check out.
if (c.SomeValue == null)
{
btnRecordCall.Enabled = false;
btnAddAction.Enabled = false;
btnProcesss.Enabled = false;
}
else
{
if(c.SomeProperty.Status != 'Y')
{
btnRecordCall.Enabled = false;
}
if((c.SomeProperty.Status != 'Y') &&
(c.SomeOtherPropertyAction != 'Y'))
{
btnAddAction.Enabled = false;
}
if(c.SomeProperty.Processing != 'Y')
{
btnProcesss.Enabled = false;
}
}
If you're looking to refactor instead of shuffle, the wall of boolean testing could be moved in to methods/extension methods of whatever class your object c is an instance of - that way you could say
btnRecordCall.Enabled = c.IsRecordCallAllowed();
Create properties on "c" such as "CanRecordCall", "CanAddAction", "CanProcess" so that your code becomes this:
btnRecordCall.Enabled = c.CanRecordCall;
btnAddAction.Enabled = c.CanAddAction;
btnProcess.Enabled = c.CanProcess;
The "c.SomeValue == null" is a typical response to NullReferenceExceptions. You could improve "c" by initializing its SomeValue property to a null object so that there is never a null reference (just an object that does nothing).
In specific, since you seem to be setting UI elements state, you could consider more of a two-way data binding model where you set up a data context and a control-to-property mapping and let that govern the control state. You can also consider a more heavy-weight solution that would be something like the Validation Application Block from Enterprise Library. There are also some fluent validation projects that you should take a look at.
I'd start by making sure all such code is contiguous. Anything other than this code should be moved before or after the code.
Then, for each reference to a control property, create a corresponding local variable, e.g., processEnabled. Define it before the first if statement. For each such property, move, e.g., btnProcesss.Enabled = false; to the end of this code block, and change "false" to processEnabled. Replace the original with processEnabled = false;.
When the code block has no more references to controls (or to anything else having to do with the UI), select the entire block, from the added variables to the control property sets at the end, and use the Extract Method refactoring. That should leave you with a method that accepts c, and produces values you can later use to set control properties.
You can even get fancier. Instead of individual local variables, define a class that has those "variables" as properties. Do pretty much the same thing, and the extracted method will wind up returning an instance of that class, instead of individual out parameters.
From there, you may start to see more things to clean up in the extracted method, not that you'll have removed anything to do with UI from that code.
I'm guessing the issue here is about 'boolean map' style refactorings, i.e., being able to refactor complementary boolean cases where there might be some gaps and some repetition. Well, if that's what you're after, you can certainly write a tool to do this (it's what I would do). Basically, you need to parse a bunch of if statements and take note of condition combinations that are involved. Then, through some fairly simple logic, you can get your model to spit out a different, more optimized model.
The code you show above is one reason why I love F#. :)
Interestingly, in our current Winforms app, the three conditions would be in three different classes, since each button would be attached to a different Command.
The conditions would be in the CanExecute methods of the commands and control the enable/disable behaviour of the button that triggers the command. The corresponding execution code is in the Execute method of the class.

Categories

Resources