-
-
Notifications
You must be signed in to change notification settings - Fork 366
Implement new concept exercise for extension methods #1585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 12 commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
f0f6eb5
concept/extension-methods docs
b488af6
calculator-extension code files
f704f69
calculator-extension docs
303d596
update list of implemented exercises
c6bf7eb
Update exercises/concept/calculator-extensions/CalculatorExtensions.c…
yzAlvin 89ec8b9
Update concepts/extension-methods/introduction.md
yzAlvin 2a12b5b
Update concepts/extension-methods/about.md
yzAlvin 1479c38
improve documentation
542a0e0
log extension method exercise
48b3385
added log exercise to config.json
84ac2e3
instructions for exercise
0ec63b3
merge conflict
2a5dd8e
Update exercises/concept/log-analysis/.docs/instructions.md
yzAlvin add9d0c
Update exercises/concept/log-analysis/.docs/instructions.md
yzAlvin b7c8fff
Update exercises/concept/log-analysis/.docs/instructions.md
yzAlvin ddaae8b
Update exercises/concept/log-analysis/LogAnalysis.csproj
yzAlvin 9f83ca5
Update exercises/concept/log-analysis/.meta/config.json
yzAlvin 7f2a9fd
Update exercises/concept/log-analysis/.docs/introduction.md
yzAlvin 22645de
Update exercises/concept/calculator-conundrum/CalculatorConundrum.cs
yzAlvin 2b0cc06
Update exercises/concept/log-analysis/.docs/hints.md
yzAlvin 24da38d
update docs
3770c25
update code files
5d458f1
Update exercises/concept/log-analysis/.docs/hints.md
yzAlvin 22437c2
Update exercises/concept/log-analysis/.docs/hints.md
yzAlvin f0dd81e
Update exercises/concept/log-analysis/.docs/instructions.md
yzAlvin 8520235
Update exercises/concept/log-analysis/LogAnalysis.cs
yzAlvin ec8c825
Update exercises/concept/log-analysis/.docs/instructions.md
yzAlvin 5227af3
Update config.json
yzAlvin 8e6c7fd
Update config.json
yzAlvin 9771aeb
Update exercises/concept/log-analysis/.docs/instructions.md
yzAlvin 30efa9d
Update exercises/concept/log-analysis/.docs/instructions.md
yzAlvin 92155c9
Update instructions.md
yzAlvin 240d946
Update Exemplar.cs
yzAlvin c788161
add mention of namespace import
152e084
add test case
18673bb
Update exercises/concept/log-analysis/.docs/instructions.md
yzAlvin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"blurb": "Extension methods allow you to add methods to existing types.", | ||
"authors": [ | ||
"yzAlvin" | ||
] | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# About | ||
|
||
[Extension methods][extension-methods] allow adding methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. | ||
|
||
Extension methods are static methods, but they're called as if they were instance methods on the extended type. It achieves this by using `this` before the type, indicating the instance we put the `.` on is passed as the first parameter. For client code, there's no apparent difference between calling an extension method and the methods defined in a type. | ||
|
||
```csharp | ||
public static int WordCount(this string str) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be nice to be a bit more explicit here and give the class a namespace, and then have a second code sample indicating another file that has a |
||
{ | ||
return str.Split().Length; | ||
} | ||
|
||
"Hello World".WordCount(); | ||
// => 2 | ||
``` | ||
|
||
A well-known example of extension methods are the [LINQ][linq] standard query operators that add query functionality to the existing IEnumerable types. | ||
|
||
[linq]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/ | ||
[extension-methods]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Introduction | ||
|
||
Extension methods allow adding methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. They are defined as static methods but are called by using instance method syntax. Their first parameter is preceded by the 'this' modifier, and specifies which type the method operates on. | ||
|
||
```csharp | ||
public static int WordCount(this string str) | ||
{ | ||
return str.Split().Length; | ||
} | ||
|
||
"Hello World".WordCount(); | ||
// => 2 | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[ | ||
{ | ||
"url": "https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods", | ||
"description": "extension-methods" | ||
} | ||
] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Hints | ||
|
||
All extension methods must be marked static | ||
All extension methods must mark `this` for the first argument | ||
yzAlvin marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# Instructions | ||
|
||
In this exercise you will be adding extension-methods on the string type to make it easier to deal with logs. Extension-methods express intent of the code, make code more readable, and add common functionality. | ||
|
||
The goal is to add extension-methods that abstract away the logic of finding out certain things about the log messages. | ||
yzAlvin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```csharp | ||
var log = "[Error]: {Line 20} - 'Critical error found'"; | ||
|
||
log.WordCount(); // => returns 7 | ||
|
||
log.LogLevel(); // => returns "Error" | ||
|
||
log.LogLine(); // => returns "20" | ||
|
||
log.Truncate(10); // => returns "[Error]: {Line 20} - 'Critical error found'" | ||
|
||
log.Truncate(5); // => returns "Error - 20" | ||
``` | ||
yzAlvin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## 1. Implement the extension method WordCount | ||
|
||
Implement the `.Word()` method to return the total of all words in the string. A 'word' in this case is just any string separated by a space. | ||
yzAlvin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## 2. Implement the extension method LogLevel | ||
|
||
Implement the `.LogLevel()` method to return the log level of the log string. | ||
|
||
## 3. Implement the extension method LogLine | ||
|
||
Implement the `.LogLine()` method to return the line the log occured at of the log string. | ||
|
||
## 4. Implement the extension method Truncate | ||
|
||
Implement the `.Truncate(int maxSize)` method to return the log message truncated to "loglevel - logline" if the message exceeds the maximum word count specified, otherwise return the original log message. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Introduction | ||
|
||
Extension methods allow adding methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. | ||
|
||
```csharp | ||
public static bool IsEven(this int number) | ||
{ | ||
return number % 2 == 0; | ||
} | ||
|
||
int isEven = 3.IsEven(); | ||
// isEven == false | ||
|
||
public static int WordCount(this string str) | ||
{ | ||
return str.Split().Length; | ||
} | ||
|
||
int wordCount = "Hello World!".WordCount(); | ||
// wordCount == 2 | ||
``` | ||
yzAlvin marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using System; | ||
|
||
public static class LogAnalysis | ||
yzAlvin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
public static int WordCount(this string log) => | ||
log.Split().Length; | ||
yzAlvin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
public static string LogLevel(this string log) => | ||
log.Substring(log.IndexOf("[") + 1, log.IndexOf("]") - 1); | ||
|
||
public static string LogLine(this string log) => | ||
log.Substring(log.IndexOf("{") + 6, log.IndexOf("}") - (log.IndexOf("{") + 6)); | ||
|
||
public static string Truncate(this string log, int maxSize) => | ||
log.WordCount() < maxSize | ||
? log | ||
: $"{log.LogLevel()} - {log.LogLine()}"; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"blurb": "Learn about extension-methods by analysing logs.", | ||
"authors": [ | ||
yzAlvin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"yzAlvin" | ||
], | ||
"files": { | ||
"solution": [ | ||
"LogAnalysis.cs" | ||
], | ||
"test": [ | ||
"LogAnalysisTests.cs" | ||
], | ||
"exemplar": [ | ||
".meta/Exemplar.cs" | ||
] | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Design | ||
|
||
## Goal | ||
|
||
The goal of this exercise is to teach the student the Concept of Extension Methods in C#. | ||
|
||
## Learning objectives | ||
|
||
- Know what extension methods are. | ||
- Know how to define extension methods on reference and value types | ||
|
||
## Out of scope | ||
|
||
- Assemblies. | ||
|
||
## Concepts | ||
|
||
- `extension-methods`: know what extension methods are; know how to define extension methods on reference and value types. | ||
|
||
## Prerequisites | ||
|
||
- `classes`: know what instance methods are. | ||
- `namespaces`: know what namespaces are; know how to import namespaces. | ||
- `collections`: know what collections are. | ||
|
||
## Resources to refer to | ||
|
||
### Hints | ||
|
||
- [Extension methods][extension-methods]: how to define extension methods. | ||
- [Namespaces][namespaces]: how to define an import namespaces. | ||
- [Collections][collections]: what a collections is. | ||
|
||
### After | ||
|
||
- [Extension methods][extension-methods]: how to define extension methods. | ||
- [Namespaces][namespaces]: how to define an import namespaces. | ||
- [Collections][collections]: what a collections is. | ||
|
||
[extension-methods]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods | ||
[namespaces]: https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/types/namespaces | ||
[collections]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/collections |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
using System; | ||
|
||
public static class LogAnalysis | ||
{ | ||
public static int WordCount(this string log) | ||
{ | ||
throw new NotImplementedException("Please implement the WordCount() extension method for strings"); | ||
} | ||
|
||
public static string LogLevel(this string log) | ||
{ | ||
throw new NotImplementedException("Please implement the LogLevel() extension method for strings"); | ||
} | ||
|
||
public static string LogLine(this string log) | ||
{ | ||
throw new NotImplementedException("Please implement the LogLine() extension method for strings"); | ||
} | ||
|
||
public static string Truncate(this string log, int maxSize) | ||
{ | ||
throw new NotImplementedException("Please implement the Truncate() extension method for strings"); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net5.0</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" /> | ||
<PackageReference Include="xunit" Version="2.4.1" /> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" /> | ||
<PackageReference Include="Exercism.Tests" Version="0.1.0-alpha" /> | ||
yzAlvin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
</ItemGroup> | ||
|
||
</Project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
using Xunit; | ||
using Exercism.Tests; | ||
using System; | ||
|
||
public class LogAnalysisTests | ||
{ | ||
[Fact] | ||
public void Word_count_of_words_in_log() | ||
{ | ||
Assert.Equal(7, "[Error]: {Line 20} - 'Critical error found'".WordCount()); | ||
} | ||
|
||
[Fact(Skip = "Remove this Skip property to run this test")] | ||
public void Word_count_of_log_with_space_separated_non_alphabet() | ||
{ | ||
Assert.Equal(6, "[Error]: {Line 3} - '; expected'".WordCount()); | ||
} | ||
|
||
[Fact(Skip = "Remove this Skip property to run this test")] | ||
public void Log_level_of_warning_log() | ||
{ | ||
Assert.Equal("Warning", "[Warning]: {Line 11} - 'Trim will be deprecated soon'".LogLevel()); | ||
} | ||
|
||
[Fact(Skip = "Remove this Skip property to run this test")] | ||
public void Log_level_of_error_log() | ||
{ | ||
Assert.Equal("Error", "[Error]: {Line 8} - '; expected'".LogLevel()); | ||
} | ||
|
||
[Fact(Skip = "Remove this Skip property to run this test")] | ||
public void Log_line_of_log_with_single_digit() | ||
{ | ||
Assert.Equal("1", "[Warning]: {Line 1} - 'Trim will be deprecated soon'".LogLine()); | ||
} | ||
|
||
[Fact(Skip = "Remove this Skip property to run this test")] | ||
public void Log_line_of_log_of_log_with_mulitple_digits() | ||
{ | ||
Assert.Equal("111", "[Warning]: {Line 111} - 'Trim will be deprecated soon'".LogLine()); | ||
} | ||
|
||
[Fact(Skip = "Remove this Skip property to run this test")] | ||
public void Truncate_log_does_not_change_log_with_less_than_10_characters() | ||
{ | ||
var log = "[Warning]: {Line 9} - 'The library bogo is deprecated.'"; | ||
Assert.Equal("[Warning]: {Line 9} - 'The library bogo is deprecated.'", log.Truncate(10)); | ||
} | ||
|
||
[Fact(Skip = "Remove this Skip property to run this test")] | ||
public void Truncate_log_trims_log_with_more_than_10_words() | ||
{ | ||
var log = "[Warning]: {Line 9} - 'The library bogo_sort is deprecated by really_quick_algorithm.'"; | ||
Assert.Equal("Warning - 9", log.Truncate(10)); | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.