Schedule matches for a season or round robin tournament
Use readable variable names. I can guess at the meaning of sch (schedule?) and  rr (round robin), but I'm at a loss for w (week?) and p. There's no reason to shorten the names, it does not affect the execution of the code; it does affect the readability. Everything might make sense to you today, but not to other people, or you in the future.
Using arrays versus lists is (at least partially) subjective), but I do think that you should be using lists here. It keeps the syntax cleaner and doesn't require readers to keep track of the array indexes.


The for loops are adding so much to the complexity. w &lt; TeamCount - 1 and p &lt; TeamCount / 2 are not easy to understand the intention. If you stick to using lists, that guides you towards using a more readable foreach statement, e.g. foreach(week in weeks)

bool awayHome = false is a very confusing name. A better name would be generateReverseMatch (or whatever designated name you prefer)
Personally, I like to keep the constructor focused on property/field assignment. I would abstract the match generation into a private method, which can still be called from the constructor: Matches = GenerateMatches(teamCount);
While not wrong per se, be on the lookout of overzealously using ToString() instead of a nicer  PrintMatches() method. Most of the time, you want a custom layout, especially if you want to have different ways of showing the same season.


Switching the code over to using lists instead of arrays is going to have a strong impact on the posted code, so I'm not sure if further code review is going to be relevant here.