How do you do Linq with non-lambda express for the following (which does not work):
string[] words = { "believe", "relief", "receipt", "field" };
var wd = (from word in words
select word).Any(Contains ("believe"));
It's not clear what good you believe the from wor in words select wor is doing - it's really not helping you at all.
It's also not clear why you don't want to use a lambda expression. The obvious approach is:
bool hasBelieve = words.Any(x => x.Contains("believe"));
Note that this isn't checking whether the list of words has the word "believe" in - it's checking whether the list of words has any word containing "believe". So "believer" would be fine. If you just want to check whether the list contains believe you can just use:
bool hasBelieve = words.Contains("believe");
EDIT: If you really want to do it without a lambda expression, you'll need to basically fake the work that the lambda expression (or anonymous method) does for you:
public class ContainsPredicate
{
private readonly string target;
public ContainsPredicate(string target)
{
this.target = target;
}
public bool Apply(string input)
{
return input.Contains(target);
}
}
Then you can use:
Func<string, bool> predicate = new ContainsPredicate("believe");
bool hasBelieve = words.Any(predicate);
Obviously you really don't want to do that though...
EDIT: Of course you could use:
var allBelieve = from word in words
where word.Contains("believe")
select word;
bool hasBelieve = allBelieve.Any();
But that's pretty ugly too - I'd definitely use the lambda expression.
You could do it like that
string[] words = { "believe", "relief", "receipt", "field" };
var wd = (from wor in words
where wor.Contains("believe")
select wor);
Related
Here's my object:
public class Symbol
{
private readonly string _identifier;
private readonly IList<Quote> _historicalQuotes;
public Symbol(string identifier, IEnumerable<Quote> historicalQuotes = null)
{
_identifier = identifier;
_historicalQuotes = historicalQuotes;
}
}
public class Quote
{
private readonly DateTime _tradingDate;
private readonly decimal _open;
private readonly decimal _high;
private readonly decimal _low;
private readonly decimal _close;
private readonly decimal _closeAdjusted;
private readonly long _volume;
public Quote(
DateTime tradingDate,
decimal open,
decimal high,
decimal low,
decimal close,
decimal closeAdjusted,
long volume)
{
_tradingDate = tradingDate;
_open = open;
_high = high;
_low = low;
_close = close;
_closeAdjusted = closeAdjusted;
_volume = volume;
}
}
I need an instance of Symbol populated with a list of Quote.
An in my test, I want to verify that I can return all quotes which the close price is under or above a specific value. Here's my test:
[Fact]
public void PriceUnder50()
{
var msftIdentifier = "MSFT";
var quotes = new List<Quote>
{
new Quote(DateTime.Parse("01-01-2009"), 0, 0, 0, 49, 0, 0),
new Quote(DateTime.Parse("01-02-2009"), 0, 0, 0, 51, 0, 0),
new Quote(DateTime.Parse("01-03-2009"), 0, 0, 0, 50, 0, 0),
new Quote(DateTime.Parse("01-04-2009"), 0, 0, 0, 10, 0, 0)
};
_symbol = new Symbol(msftIdentifier, quotes);
var indicator = new UnderPriceIndicator(50);
var actual = indicator.Apply(_symbol);
Assert.Equal(2, actual.Count);
Assert.True(actual.Any(a => a.Date == DateTime.Parse("01-01-2009")));
Assert.True(actual.Any(a => a.Date == DateTime.Parse("01-04-2009")));
Assert.True(actual.Any(a => a.Price == 49));
Assert.True(actual.Any(a => a.Price == 10));
}
OK.
Now, I wanna do it using Autofixture, im a real beginner. I've read pretty much everything I could on internet about this tool (the author's blog, codeplex FAQ, github source code). I understand the basic features of autofixture, but now I wanna use autofixture in my real project. Here's what I tried so far.
var msftIdentifier = "MSFT";
var quotes = new List<Quote>();
var random = new Random();
fixture.AddManyTo(
quotes,
() => fixture.Build<Quote>().With(a => a.Close, random.Next(1,49)).Create());
quotes.Add(fixture.Build<Quote>().With(a => a.Close, 49).Create());
_symbol = new Symbol(msftIdentifier, quotes);
// I would just assert than 49 is in the list
Assert.True(_symbol.HistoricalQuotes.Contains(new Quote... blabla 49));
Ideally, I would prefer to directly create a fixture of Symbol, but I don't know how to customize my list of quotes. And I'm not sure that my test is generic, because, in another test, I will need to check that a specific value is above instead of under, so I'm gonna duplicate the "fixture code" and manual add a quote = 51.
So my questions are:
1 - Is it the way how I'm supposed to use autofixture?
2 - Is it possible to improve the way I use autofixture in my example ?
AutoFixture was originally build as a tool for Test-Driven Development (TDD), and TDD is all about feedback. In the spirit of GOOS, you should listen to your tests. If the tests are hard to write, you should consider your API design. AutoFixture tends to amplify that sort of feedback, and here's what it's telling me.
Make comparison easier
First, while not related to AutoFixture, the Quote class just begs to be turned into a proper Value Object, so I'll override Equals to make it easier to compare expected and actual instances:
public override bool Equals(object obj)
{
var other = obj as Quote;
if (other == null)
return base.Equals(obj);
return _tradingDate == other._tradingDate
&& _open == other._open
&& _high == other._high
&& _low == other._low
&& _close == other._close
&& _closeAdjusted == other._closeAdjusted
&& _volume == other._volume;
}
(Make sure to override GetHashCode too.)
Copy and update
The above attempt at a test seems to imply that we're lacking a way to vary a single field while keeping the rest constant. Taking a cue from functional languages, we can introduce a way to do that on the Quote class itself:
public Quote WithClose(decimal newClose)
{
return new Quote(
_tradingDate,
_open,
_high,
_low,
newClose,
_closeAdjusted,
_volume);
}
This sort of API tends to be very useful on Value Objects, to the point where I always add such methods to my Value Objects.
Let's do the same with Symbol:
public Symbol WithHistoricalQuotes(IEnumerable<Quote> newHistoricalQuotes)
{
return new Symbol(_identifier, newHistoricalQuotes);
}
This makes it much easier to ask AutoFixture to deal with all the stuff you don't care about while explicitly stating only that which you care about.
Testing with AutoFixture
The original test can now be rewritten as:
[Fact]
public void PriceUnder50()
{
var fixture = new Fixture();
var quotes = new[]
{
fixture.Create<Quote>().WithClose(49),
fixture.Create<Quote>().WithClose(51),
fixture.Create<Quote>().WithClose(50),
fixture.Create<Quote>().WithClose(10),
};
var symbol = fixture.Create<Symbol>().WithHistoricalQuotes(quotes);
var indicator = fixture.Create<UnderPriceIndicator>().WithLimit(50);
var actual = indicator.Apply(symbol);
var expected = new[] { quotes[0], quotes[3] };
Assert.Equal(expected, actual);
}
This test only states those parts of the test case that you care about, while AutoFixture takes care of all the other values that don't have any impact on the test case. This makes the test more robust, as well as more readable.
Is there a way to implement an extension method to a generic type that takes in arguments a Func of another type?
For exemple, a usage something similar to this:
myFirstObject.Extension<myOtherObject>( other => other.Prop );
Or with a more complicated Func:
myFirstObject.Extension<myOtherObject>( other => other.Prop > 2 && other.Prop < 15 );
I found some related question like this one, but in my case, I need generic types inside the extension method too.
Here's what I came up with:
public static bool Extension<TSource, TIn, TKey>(this TSource p_Value, Expression<Func<TIn, TKey>> p_OutExpression)
{ return true; }
However, when I try to use it, it does not take into consideration the second type.
Am I missing something?
Look at this:
s => s.Length;
How's the compiler suppose to know whether or not s is a string or s is an array or some other type that has a Length property? It can't, unless you give it some information:
(string s) => s.Length;
Oh, there we go. So now, try this:
myFirstObject.Extension((myOtherObject o) => o.Prop > 2 && o.Prop < 15);
That will work, because you've told the compiler what it should use for TIn, and it can figure out what to use for TKey based on the expression.
I found that another solution would be to create another method that takes in argument a type.
For instance:
Void Extension(Type p_Type, [THE TYPE] p_Params)
{
MethodInfo realExtensionMethod = typeof([CLASS CONTAINING THE METHOD]).GetMethod("RealExtension");
realExtensionMethod = realExtensionMethod.MakeGenericMethod(p_Type);
realExtensionMethod.Invoke(null, new object[] {p_Type, p_Params });
}
Void RealExtension<TYPE>(params)
{
}
Then at usage time:
Type objectType = typeof(myOtherObject);
myFirstObject.Extension(objectType, other => other.Prop );
When you call a generic method in C# you can explicitly declare all of the generic type parameters or you can have them all inferred, but you cannot have some explicitly declared and some inferred.
So, if I had this method:
public void Foo<X, Y>(X x, Y y)
{
/* Do somethhing */
}
Then here's what works and what doesn't:
int a = 42;
string b = "Hello, World!";
// Legal
Foo(a, b);
Foo<int, string>(a, b);
//Illegal
Foo<int>(a, b);
The best you can do is move the first generic parameter up to the class level, but not it won't work as an extension method. Nevertheless you may like this approach.
public static class Class<TSource>
{
public static bool Method<TIn, TKey>(
TSource p_Value,
Expression<Func<TIn, TKey>> p_OutExpression)
{
return true;
}
}
Now you can call it like this:
Expression<Func<long, decimal>> f =
l => (decimal)l;
var result = Class<int>.Method(a, f);
But as I say, it won't work as an extension method now.
I'm trying to build a dynamic query whit a condition on an emum
enumField & enumValue == enumValue
for this, during the analysis the following is called
Expression GenerateBitWiseAnd(Expression left, Expression right) {
return Expression.And(left, right);
}
this throws an exception
And binary operator is not defined for `EnumType` and `EnumType`.
The equality operator runs well
Expression GenerateEqual(Expression left, Expression right) {
return Expression.Equal(left, right);
}
But I can't figure how to handle a [Flags] without the And bits operator.
The question is: from here how to dynamically forge my query to check my enum.
My application is targeting .Net 4
You'll need to convert the Enum to its underlying type before you can operate on it:
Expression GenerateBitWiseAnd(Expression left, Expression right)
{
if (left.Type.IsEnum)
{
var enumType = left.Type;
var compareType = Enum.GetUnderlyingType(enumType);
var enumField = Expression.Convert(left, compareType);
var enumValue = Expression.Convert(right, compareType);
var and = Expression.And(enumField, enumValue);
return Expression.Convert(and, enumType);
}
return Expression.And(left, right);
}
I've been following the Tasky Case Study on the MonoDroid website, but I've run into a wall whilst creating a filtering and ordering query. I was wondering if somebody could explain where I might be going wrong please? I'm probably doing something completely backwards!
I get the error:
The type arguments for method 'ICanTalk.BusinessLayer.Services.WordServices.Find(System.Func, System.Func, bool, int, int)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
I have the following code in one of my repositories, hopefully what I'm trying to do is kind of clear. I haven't been able to build it yet to test to see if it works though:
public static IEnumerable<Word> Find<T,U>(Func<Word, bool> whereClause, Func<Word,U> orderBy, bool ascending, int show, int page)
{
int currentPage = page;
int resultsPerPage = show;
int skip = currentPage*show;
var result = ascending
? me.db.Find<Word>().Where(whereClause).OrderBy(orderBy).Take(resultsPerPage).Skip(skip)
: me.db.Find<Word>().Where(whereClause).OrderByDescending(orderBy).Take(resultsPerPage).Skip(skip);
return result;
}
From my services I call this method from here:
public static IList<Word> Find<T>(Func<Word, bool> whereClause, Func<Word,DateTime> orderBy, bool ascending, int show, int page)
{
return WordRepository.Find<Word, DateTime>(whereClause, orderBy, ascending, show, page).ToList();
}
What I'm trying to achieve is a call from an event handler within MonoDroid like:
var wordTest = WordServices.Find(x => x.ChildId == 3, x => x.AddedAt, true, 5, 1);
Both of your methods are generic Find<T,U> and Find<T> - but you don't seem to be using the type T anywhere in your method definition. Was T expected to be the type Word ?
U is used once in the orderBy where elsewhere you're using bool - which of those usages is a mistake?
Can you try replacing Word with T in your definitions, and bool with U (if that's what you meant to do) and then when you're calling the method actually call it with the correct type ?
var wordTest = WordServices.Find<Word>(x => x.ChildId == 3,
x => x.AddedAt,
true, 5, 1);
I had it almost right, I stripped it down to the basics and worked my way back up and came up with the following (compare to original if you're interested).
SQLiteDatabase.cs
(not in original post - I scaled the query clauses right down to a reusable method in my generic handler):
public IEnumerable<T> Find<T>(Func<T, bool> whereClause, int resultsToSkip, int resultsToShow)
where T : BusinessLayer.Contracts.IBusinessEntity, new()
{
lock (locker)
{
return Table<T>().Where(whereClause).Skip(resultsToSkip).Take(resultsToShow).ToList();
}
}
WordRepository.cs
public static IEnumerable<Word> Find<T>(Func<Word, bool> whereClause, int resultsToSkip, int resultsToShow)
where T : BusinessLayer.Contracts.IBusinessEntity, new()
{
var result = me.db.Find<Word>(whereClause, resultsToSkip, resultsToShow);
return result;
}
WordServices.cs
By this point I'm wondering why there exists a need for so many layers - will definitley look to refactor in the morning.
public static IList<Word> Find<T, U>(Func<Word, bool> whereClause, Func<Word, U> orderBy, bool ascending, int show, int page)
{
int resultsToShow = show;
int resultsToSkip = show * (page - 1);
var result = ascending ? WordRepository.Find<Word>(whereClause, resultsToSkip, resultsToShow).OrderBy(orderBy)
: WordRepository.Find<Word>(whereClause, resultsToSkip, resultsToShow).OrderByDescending(orderBy);
return result.ToList();
}
Originating Call
var wordTest1 = WordServices.Find<Word, DateTime>(x => x.ChildId == 1, x => x.AddedAt, true, 5, 1);
I have two list of members like this:
Before: Peter, Ken, Julia, Tom
After: Peter, Robert, Julia, Tom
As you can see, Ken is is out and Robert is in.
What I want is to detect the changes. I want a list of what has changed in both lists. How can linq help me?
Your question is not completely specified but I assume that you are looking for the differences as sets (that is, ordering does not matter). If so, you want the symmetric difference of the two sets. You can achieve this using Enumerable.Except:
before.Except(after).Union(after.Except(before));
As an alternative to linq answers, which have to pass both lists twice, use HashSet.SymmetricExceptWith():
var difference = new HashSet(before);
difference.SymmetricExceptWith(after);
Could be considerably more efficient.
Another way:
before.Union(after).Except(before.Intersect(after))
Here is the version having O(n) complexity, provided your sequences are both ordered:
public static IEnumerable<T> SymmetricDifference<T>(IEnumerable<T> coll1, IEnumerable<T> coll2, IComparer<T> cmp)
{
using (IEnumerator<T> enum1 = coll1.GetEnumerator())
using (IEnumerator<T> enum2 = coll2.GetEnumerator())
{
bool enum1valid = enum1.MoveNext();
bool enum2valid = enum2.MoveNext();
while (enum1valid && enum2valid)
{
int cmpResult = cmp.Compare(enum1.Current, enum2.Current);
if (cmpResult < 0)
{
yield return enum1.Current;
enum1valid = enum1.MoveNext();
}
else if (cmpResult > 0)
{
yield return enum2.Current;
enum2valid = enum2.MoveNext();
}
else
{
enum1valid = enum1.MoveNext();
enum2valid = enum2.MoveNext();
}
}
while (enum1valid)
{
yield return enum1.Current;
enum1valid = enum1.MoveNext();
}
while (enum2valid)
{
yield return enum2.Current;
enum2valid = enum2.MoveNext();
}
}
}
public static IEnumerable<T> SymmetricDifference<T>(IEnumerable<T> coll1, IEnumerable<T> coll2)
{
return SymmetricDifference(coll1, coll2, Comparer<T>.Default);
}