Reputation: 113
I have two classes: TextElement
that is a selenium extension with some text properties (Text returns the string of the element) and the other is ArrayTextElement
that basically is an array of TextElement
objects.
/// <summary>
/// Finds the first element that matches the text
/// </summary>
public static TextElement Find(this ArrayTextElement<TextElement > list, string text)
{
try
{
return list.Items.First(item => item.Text.Equals(text));
}
catch (Exception)
{
throw new NotFoundException($"Requested element with text: '{text}' wasn't found.");
}
}
/// <summary>
/// Finds the first element that contains the text
/// </summary>
public static TextElement FindByContains(this ArrayTextElement<TextElement > list, string text)
{
try
{
return list.Items.First(item => item.Text.Contains(text));
}
catch (Exception)
{
throw new NotFoundException($"Requested element with text: '{text}' wasn't found.");
}
}
The real issue is that I need to unify those 2 functions into 1. So I want to send the Equals
and Contains
functions that extend from String, as a parameter.
Upvotes: 0
Views: 81
Reputation: 2481
If I understand you correctly, you can pass an additional parameter to indicate if you want to use an exact match or a partial. The following is good if you the only searches you want to do are exact or partial. The other answers given here are far more versatile, but this version is a little easier to maintain.
public static TextElement Find(this ArrayTextElement<TextElement> list, string text, bool exactMatch)
{
try
{
return list.Items.First(item => exactMatch ?
item.Text.Equals(text) :
item.Text.Contains(text)
);
}
catch (Exception)
{
throw new NotFoundException($"Requested element with text: '{text}' wasn't found.");
}
}
To use it:
TextElement textElem = list.Find("abcdef", [true|false]);
Upvotes: 1
Reputation: 7091
You can refactor both methods into one by passing a Func<string, bool>
and using that function inside your first. So what you have now becomes:
public static TextElement Find(this ArrayTextElement<TextElement> list, Func<string, bool> predicate)
{
try
{
return list.Items.First(item => predicate(item.Text));
}
catch (Exception)
{
throw new NotFoundException($"Requested element with text: '{text}' wasn't found.");
}
}
And to call it with either Contains
or Equals
you would do this:
public void UsingTheMethod()
{
ArrayTextElement<TextElement> list = new ArrayTextElement<TextElement>();
string someText = string.Empty;
Find(list, s => s.Equals(someText));
Find(list, s => s.Contains(someText));
}
Upvotes: 3
Reputation: 4658
You can simply pass a Func<string, bool>
like so:
public static TextElement Find(this ArrayTextElement<TextElement> list, Func<string, bool> predicate)
{
try
{
return list.Items.First(item => predicate(item.Text));
}
catch (Exception)
{
throw new NotFoundException($"Requested element with text: '{text}' wasn't found.");
}
}
And call it like this:
var text = // whatever;
var element = elements.Find(s => s.Equals(text));
Upvotes: 2