Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 69 additions & 147 deletions docs/csharp/event-pattern.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/fundamentals/code-analysis/quality-rules/ca1070.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ ms.author: mavasani

## Cause

A [field-like event](../../../csharp/event-pattern.md#defining-and-raising-field-like-events) was declared as virtual.
A [field-like event](../../../csharp/event-pattern.md#define-and-raise-field-like-events) was declared as virtual.

By default, this rule only looks at externally visible types, but this is [configurable](#configure-code-to-analyze).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ Design rules support adherence to the [.NET Framework design guidelines](../../.
| [CA1067: Override Equals when implementing IEquatable](ca1067.md) | A type implements <xref:System.IEquatable%601>, but does not override <xref:System.Object.Equals%2A> method. |
| [CA1068: CancellationToken parameters must come last](ca1068.md) | A method has a CancellationToken parameter that is not the last parameter. |
| [CA1069: Enums should not have duplicate values](ca1069.md) | An enumeration has multiple members which are explicitly assigned the same constant value. |
| [CA1070: Do not declare event fields as virtual](ca1070.md) | A [field-like event](../../../csharp/event-pattern.md#defining-and-raising-field-like-events) was declared as virtual. |
| [CA1070: Do not declare event fields as virtual](ca1070.md) | A [field-like event](../../../csharp/event-pattern.md#define-and-raise-field-like-events) was declared as virtual. |
2 changes: 1 addition & 1 deletion docs/fundamentals/code-analysis/quality-rules/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ The following table lists code quality analysis rules.
> | [CA1067: Override Equals when implementing IEquatable](ca1067.md) | A type implements <xref:System.IEquatable%601>, but does not override <xref:System.Object.Equals%2A> method. |
> | [CA1068: CancellationToken parameters must come last](ca1068.md) | A method has a CancellationToken parameter that is not the last parameter. |
> | [CA1069: Enums should not have duplicate values](ca1069.md) | An enumeration has multiple members which are explicitly assigned the same constant value. |
> | [CA1070: Do not declare event fields as virtual](ca1070.md) | A [field-like event](../../../csharp/event-pattern.md#defining-and-raising-field-like-events) was declared as virtual. |
> | [CA1070: Do not declare event fields as virtual](ca1070.md) | A [field-like event](../../../csharp/event-pattern.md#define-and-raise-field-like-events) was declared as virtual. |
> | [CA1200: Avoid using cref tags with a prefix](ca1200.md) | The [cref](../../../csharp/language-reference/xmldoc/recommended-tags.md) attribute in an XML documentation tag means "code reference". It specifies that the inner text of the tag is a code element, such as a type, method, or property. Avoid using `cref` tags with prefixes, because it prevents the compiler from verifying references. It also prevents the Visual Studio integrated development environment (IDE) from finding and updating these symbol references during refactorings. |
> | [CA1303: Do not pass literals as localized parameters](ca1303.md) | An externally visible method passes a string literal as a parameter to a .NET constructor or method, and that string should be localizable. |
> | [CA1304: Specify CultureInfo](ca1304.md) | A method or constructor calls a member that has an overload that accepts a System.Globalization.CultureInfo parameter, and the method or constructor does not call the overload that takes the CultureInfo parameter. When a CultureInfo or System.IFormatProvider object is not supplied, the default value that is supplied by the overloaded member might not have the effect that you want in all locales. |
Expand Down
8 changes: 0 additions & 8 deletions samples/snippets/csharp/events/NuGet.Config

This file was deleted.

60 changes: 32 additions & 28 deletions samples/snippets/csharp/events/Program.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.IO;

namespace EventSampleCode
{
Expand All @@ -15,7 +9,7 @@ static void Main(string[] args)
// <SnippetDeclareEventHandler>
var fileLister = new FileSearcher();
int filesFound = 0;

EventHandler<FileFoundArgs> onFileFound = (sender, eventArgs) =>
{
Console.WriteLine(eventArgs.FoundFile);
Expand Down Expand Up @@ -45,12 +39,9 @@ static void Main(string[] args)
public class FileFoundArgs : EventArgs
{
public string FoundFile { get; }
public bool CancelRequested { get; set;}
public bool CancelRequested { get; set; }

public FileFoundArgs(string fileName)
{
FoundFile = fileName;
}
public FileFoundArgs(string fileName) => FoundFile = fileName;
}
// </SnippetEventArgs>

Expand Down Expand Up @@ -78,10 +69,10 @@ public class FileSearcher
// <SnippetDeclareSearchEvent>
internal event EventHandler<SearchDirectoryArgs> DirectoryChanged
{
add { directoryChanged += value; }
remove { directoryChanged -= value; }
add { _directoryChanged += value; }
remove { _directoryChanged -= value; }
}
private EventHandler<SearchDirectoryArgs> directoryChanged;
private EventHandler<SearchDirectoryArgs> _directoryChanged;
// </SnippetDeclareSearchEvent>

// <SnippetFinalImplementation>
Expand All @@ -94,32 +85,45 @@ public void Search(string directory, string searchPattern, bool searchSubDirs =
var totalDirs = allDirectories.Length + 1;
foreach (var dir in allDirectories)
{
directoryChanged?.Invoke(this,
new SearchDirectoryArgs(dir, totalDirs, completedDirs++));
RaiseSearchDirectoryChanged(dir, totalDirs, completedDirs++);
// Search 'dir' and its subdirectories for files that match the search pattern:
SearchDirectory(dir, searchPattern);
}
// Include the Current Directory:
directoryChanged?.Invoke(this,
new SearchDirectoryArgs(directory, totalDirs, completedDirs++));
RaiseSearchDirectoryChanged(directory, totalDirs, completedDirs++);

SearchDirectory(directory, searchPattern);
}
else
{
SearchDirectory(directory, searchPattern);
}
}

private void SearchDirectory(string directory, string searchPattern)
{
foreach (var file in Directory.EnumerateFiles(directory, searchPattern))
{
var args = new FileFoundArgs(file);
FileFound?.Invoke(this, args);
FileFoundArgs args = RaiseFileFound(file);
if (args.CancelRequested)
{
break;
}
}
}

private void RaiseSearchDirectoryChanged(
string directory, int totalDirs, int completedDirs) =>
_directoryChanged?.Invoke(
this,
new SearchDirectoryArgs(directory, totalDirs, completedDirs));

private FileFoundArgs RaiseFileFound(string file)
{
var args = new FileFoundArgs(file);
FileFound?.Invoke(this, args);
return args;
}
// </SnippetFinalImplementation>
}
}
Expand All @@ -131,10 +135,7 @@ public class FileFoundArgs : EventArgs
{
public string FoundFile { get; }

public FileFoundArgs(string fileName)
{
FoundFile = fileName;
}
public FileFoundArgs(string fileName) => FoundFile = fileName;
}
// </SnippetEventArgsV1>

Expand All @@ -147,9 +148,12 @@ public void Search(string directory, string searchPattern)
{
foreach (var file in Directory.EnumerateFiles(directory, searchPattern))
{
FileFound?.Invoke(this, new FileFoundArgs(file));
RaiseFileFound(file);
}
}

private void RaiseFileFound(string file) =>
FileFound?.Invoke(this, new FileFoundArgs(file));
}
// </SnippetFileSearcherV1>
}
3 changes: 2 additions & 1 deletion samples/snippets/csharp/events/events.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

</Project>