Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't create new MatchCollection -- no constructors defined

Tags:

c#

So, maybe I'm tired, but why can't I create a new MatchCollection?

I have a method that returns a MatchCollection by calling regex.Matches:

public static MatchCollection GetStringsWithinBiggerString(string sourceString)
{
    Regex regex = new Regex(@"\$\(.+?\)");

    return regex.Matches(sourceString);
}

What I wanted to do was return an empty collection if the parameter was null:

public static MatchCollection GetStringsWithinBiggerString(string sourceString)
{
    if (sourceString == null)
    {
        return new MatchCollection();
    }

    Regex regex = new Regex(@"\$\(.+?\)");

    return regex.Matches(sourceString);
}

But that won't compile because of this line:

return new MatchCollection();

The error:

The type 'System.Text.RegularExpressions.MatchCollection' has no constructors defined.

How can a type have no constructors defined? I thought a default constructor would be created if no constructor was explicitly defined. Is it not possible to create a new instance of MatchCollection for my method to return?

like image 573
Bob Horn Avatar asked Dec 27 '22 06:12

Bob Horn


2 Answers

Very appropriate use of the Null Object pattern!

Implement like this:

public static MatchCollection GetStringsWithinBiggerString(string sourceString)
{
    Regex regex = new Regex(@"\$\(.+?\)");

    return regex.Matches(sourceString ?? String.Empty);
}
like image 86
Tom Blodget Avatar answered Jan 30 '23 14:01

Tom Blodget


How can a type have no constructors defined?

It can't. But it can hide all of its constructors by making them non-public - i.e. private, internal, or protected. Moreover, once a constructor is defined, the default constructor becomes inaccessible. Other classes in the same namespace can access internal constructors, but the classes external to the namespace would not be able to instantiate a class directly.

P.S. If you would like to create an empty match collection, you can always make an expression that matches something, and pass it something else:

Regex regex = new Regex(@"foo");
var empty = regex.Matches("bar"); // "foo" does not match "bar"
like image 44
Sergey Kalinichenko Avatar answered Jan 30 '23 14:01

Sergey Kalinichenko