这是indexloc提供的服务,不要输入任何密码
Skip to content
This repository was archived by the owner on Jan 14, 2025. It is now read-only.
Closed

Yi #56

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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -358,3 +358,6 @@ NuGet.config
# MacOS files
.DS_Store
**/.trydotnet-builderror

# NCrunch
*ncrunch*
16 changes: 16 additions & 0 deletions Documentation/Revisit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
1. Where static value type member is allocated?
**On `Loader Heap`**. It can be shared by multiple threads. It is not boxed. It is not allocated on the stack.
[**SO question*](https://stackoverflow.com/questions/25741795/is-a-static-value-type-field-boxed-in-the-heap-in-c)

1. What is the advantage of `Task` over `Thread`?

1. `SynchronizationContext`

https://docs.microsoft.com/en-us/archive/msdn-magazine/2011/february/msdn-magazine-parallel-computing-it-s-all-about-the-synchronizationcontext

> 1) One aspect of SynchronizationContext is that it provides a way to queue a unit of work to a context. Note that this unit of work is queued to a context rather than a specific thread.


> 2) Another aspect of SynchronizationContext is that every thread has a “current” context. A thread’s context isn’t necessarily unique; its context instance may be shared with other threads. It’s possible for a thread to change its current context, but this is quite rare.

> 3) A third aspect of SynchronizationContext is that it **keeps a count of** outstanding asynchronous operations.
8 changes: 8 additions & 0 deletions csharp8/CodingGame.Enemy/CodingGame.Enemy.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

</Project>
92 changes: 92 additions & 0 deletions csharp8/CodingGame.Enemy/Player.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using System;
using System.Linq;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;

/**
* The code below will read all the game information for you.
* On each game turn, information will be available on the standard input, you will be sent:
* -> the total number of visible enemies
* -> for each enemy, its name and distance from you
* The system will wait for you to write an enemy name on the standard output.
* Once you have designated a target:
* -> the cannon will shoot
* -> the enemies will move
* -> new info will be available for you to read on the standard input.
*
*
*
* Votre programme doit détruire les vaisseaux ennemis en tirant sur l'ennemi le plus proche à chaque tour.
Règles
Les vaisseaux ennemis approchent en ligne droite vers votre canon.

À chaque début d'un tour de jeu (dans la boucle game loop), vous obtenez les informations des deux ennemis
les plus proches :
variable enemy1 : le nom de l'ennemi 1.
variable dist1 : la distance à laquelle se trouve l'ennemi 1.
variable enemy2 : le nom de l'ennemi 2.
variable dist2 : la distance à laquelle se trouve l'ennemi 2.
Avant la fin du tour (fin de la boucle), vous devez indiquer en sortie le nom de l'ennemi le plus proche.
Pour afficher le nom de l'ennemi le plus proche, vous devez utiliser la variable enemy1 ou enemy2.
**/
class Player
{

static void Main(string[] args)
{
// game loop
while (true)
{

int minDistance = 1000;
string closestEnemy = null;


if (!int.TryParse(Console.ReadLine(), out int count))
{
Console.WriteLine("Invalid arguments.");
continue;
}

for (int i = 0; i < count; i++)
{
try
{
(string enemy, int dist) = ParseEnemyInfo(Console.ReadLine());
if (dist < minDistance)
{
minDistance = dist;
closestEnemy = enemy;
}
}
catch (ArgumentException)
{
Console.WriteLine("Invalid arguments.");
continue;
}

}

// Write an action using Console.WriteLine()
// To debug: Console.Error.WriteLine("Debug messages...");
Console.Out.WriteLine(closestEnemy);
//Console.WriteLine("HotDroid"); // The name of the most threatening enemy (HotDroid is just one example)
}
}

private static (string enemy, int dist) ParseEnemyInfo(string rawEnemy)
{
string[] components = Regex.Split(rawEnemy, @"\s+");
if (components.Length != 2
|| !int.TryParse(components[1].Substring(0, components[1].Length - 1), out int distance))
{
throw new ArgumentException("Invalid enemy info");
}

var enemy = components[0];
return (enemy, distance);
}
}
39 changes: 39 additions & 0 deletions csharp8/ExploreCsharpEight.Tests/AsyncStreamShould.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NFluent;
using NUnit.Framework;

namespace ExploreCsharpEight.Tests
{
[TestFixture]
public class AsyncStreamShould
{
public static async System.Collections.Generic.IAsyncEnumerable<int> GenerateSequence()
{
for (int i = 0; i < 20; i++)
{
await Task.Delay(1);
yield return i;
}
}

public async Task<IEnumerable<int>> Consume(IAsyncEnumerable<int> stream)
{
var list = new List<int>();
await foreach (var i in stream)
{
list.Add(i);
}

return list;
}

[Test]
public async Task Can_get_future_list()
{
var result = await Consume(GenerateSequence());
Check.That(result).ContainsExactly(Enumerable.Range(0, 20));
}
}
}
15 changes: 15 additions & 0 deletions csharp8/ExploreCsharpEight.Tests/Event.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace ExploreCsharpEight.Tests
{
public abstract class Event
{

}

public class OrderReceived : Event
{
}

public class OrderAccepted : Event
{
}
}
17 changes: 17 additions & 0 deletions csharp8/ExploreCsharpEight.Tests/ExploreCsharpEight.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<LangVersion>8.0</LangVersion>
<IsPackable>false</IsPackable>
</PropertyGroup>


<ItemGroup>
<PackageReference Include="nfluent" Version="2.7.0" />
<PackageReference Include="nunit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
</ItemGroup>

</Project>
34 changes: 34 additions & 0 deletions csharp8/ExploreCsharpEight.Tests/PatternMatchingCSharp7Should.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;

namespace ExploreCsharpEight.Tests
{

public class PatternMatchingCSharp7Should
{
public class OrderManager
{
public void Notify(Event evt)
{
switch (evt)
{
case OrderReceived orderReceived:
Handle(orderReceived);
break;
case OrderAccepted orderAccepted:
Handle(orderAccepted);
break;
default:
throw new ArgumentException();
}
}

private void Handle(OrderReceived orderReceived)
{
}

private void Handle(OrderAccepted orderAccepted)
{
}
}
}
}
63 changes: 63 additions & 0 deletions csharp8/ExploreCsharpEight.Tests/RegularExpressionShould.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System;
using System.Text.RegularExpressions;
using NFluent;
using NUnit.Framework;
using NUnit.Framework.Internal;

namespace ExploreCsharpEight.Tests
{
[TestFixture]
public class RegularExpressionShould
{
[TestCase("toto 15", true)]
[TestCase("toto6966 15", true)]
[TestCase("toto6966 15d", false)]
[TestCase("toto6966 15", true)]
[TestCase("42 15", true)]
public void Match_string_space_integer(string input, bool expectedMatch)
{
var regex = new Regex(@"^\w+\s+\d+$");
bool match = regex.IsMatch(input);

Check.That(match).IsEqualTo(expectedMatch);
}

[Test]
public void Match_one_value()
{
// Step 1: create new Regex.
Regex regex = new Regex(@"\d+");

// Step 2: call Match on Regex instance.
Match match = regex.Match("Dot 55 Perls");

// Step 3: test for Success.
if (match.Success)
{
Console.WriteLine("MATCH VALUE: " + match.Value);
}
}

[Test]
public void Take_out_matching_values()
{
// Part 1: the input string.
string input = "/content/alternate-1.aspx";

// Part 2: call Regex.Match.
Match match = Regex.Match(input, @"content/([A-Za-z0-9\-]+)\.aspx$",
RegexOptions.IgnoreCase);

// Part 3: check the Match for Success.
if(!match.Success)
Assert.Fail("Not match");


// Part 4: get the Group value and display it.
Check.That(match.Groups).HasSize(2);

Check.That(match.Groups[0].Value).IsEqualTo("content/alternate-1.aspx");
Check.That(match.Groups[1].Value).IsEqualTo("alternate-1");
}
}
}
41 changes: 41 additions & 0 deletions csharp8/ExploreCsharpEight.Tests/TaskYieldShould.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System.Threading;
using System.Threading.Tasks;
using NFluent;
using NUnit.Framework;

namespace ExploreCsharpEight.Tests
{
[TestFixture]
public class TaskYieldShould
{
[Test]
public async Task Without_task_yield_actually_get_a_real_blocking_method_call()
{
var capture = Thread.CurrentThread.ManagedThreadId;
var threadOfAsyncOp = await DoFakeAsync();
Check.That(threadOfAsyncOp).IsEqualTo(capture);
}

[Test]
public async Task With_task_yield()
{
var capture = Thread.CurrentThread.ManagedThreadId;

await Task.Yield(); // Task.Yield force to the await operation to start in a different thread.
// https://stackoverflow.com/questions/22645024/when-would-i-use-task-yield

var threadOfAsyncOp = await DoFakeAsync();
Check.That(threadOfAsyncOp).IsNotEqualTo(capture);
}

/// <summary>
/// Nothing can ensure under the cover of async modifier, it is really a non blocking operation.
/// </summary>
/// <returns></returns>
private async Task<int> DoFakeAsync()
{
Thread.Sleep(1);
return Thread.CurrentThread.ManagedThreadId;
}
}
}
Loading