PI06 i PI06-1. Docker definitions for MSSQL and Postgres. Data seeder/generator for countries and people. Entity Framework example with variants for Postgres and MSSQL
This commit is contained in:
10
DefensiveProgramming/Barricades/Barricades.csproj
Normal file
10
DefensiveProgramming/Barricades/Barricades.csproj
Normal file
@@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
53
DefensiveProgramming/Barricades/Course.cs
Normal file
53
DefensiveProgramming/Barricades/Course.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Barricades;
|
||||
|
||||
class Course(string name)
|
||||
{
|
||||
public string Name { get; private set; } = name;
|
||||
|
||||
//Consider why is dictionary private variable, and why not a property!
|
||||
//indexer serves as a barricade
|
||||
|
||||
private Dictionary<string, int> grades = new Dictionary<string, int>();
|
||||
|
||||
/// <summary>
|
||||
/// Assign the new grade to the student.
|
||||
/// Old value (if had existed) is replaced.
|
||||
/// </summary>
|
||||
/// <param name="name">Student's name</param>
|
||||
/// <returns>The student's grade or -1 if the student does not have a grade</returns>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">Thrown if value is not valid grade [1-5]</exception>
|
||||
public int this[string name]
|
||||
{
|
||||
get
|
||||
{
|
||||
//what if there is no student's name in the dictionary
|
||||
//throw exception, return special value? See error handling techniques
|
||||
bool exists = grades.TryGetValue(name, out int grade);
|
||||
return exists ? grade : -1;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 1 || value > 5)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException($"Invalid grade {value}. It shoud be from 1 to 5");
|
||||
}
|
||||
|
||||
grades[name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public double AverageGrade()
|
||||
{
|
||||
int sum = 0;
|
||||
foreach (var pair in grades)
|
||||
{
|
||||
int grade = pair.Value;
|
||||
Debug.Assert(grade >= 1 && grade <= 5,
|
||||
$"Invalid grade in dictionary {pair.Key} = {pair.Value}. This should never happens!");
|
||||
sum += grade;
|
||||
}
|
||||
return grades.Count > 0 ? (double)sum / grades.Count : 0;
|
||||
}
|
||||
}
|
||||
14
DefensiveProgramming/Barricades/Program.cs
Normal file
14
DefensiveProgramming/Barricades/Program.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using Barricades;
|
||||
using System.Text;
|
||||
|
||||
Console.OutputEncoding = Encoding.UTF8;
|
||||
|
||||
Course c = new Course("PI");
|
||||
c["Pero"] = 2;
|
||||
c["Ana"] = 5;
|
||||
c["Ivan"] = 5;
|
||||
c["Marko"] = 1;
|
||||
c["Luka"] = 3;
|
||||
//c["Marija"] = -7; //should throw an exception
|
||||
Console.WriteLine("Average grade: " + c.AverageGrade());
|
||||
Console.WriteLine("Šime has grade: " + c["Šime"]); //prints -1
|
||||
14
DefensiveProgramming/Conditional/Conditional.csproj
Normal file
14
DefensiveProgramming/Conditional/Conditional.csproj
Normal file
@@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DefineConstants>TRACE;DEMO</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
20
DefensiveProgramming/Conditional/Program.cs
Normal file
20
DefensiveProgramming/Conditional/Program.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
#define DEMO2
|
||||
|
||||
using System.Diagnostics;
|
||||
|
||||
Console.WriteLine("Start");
|
||||
|
||||
#if DEMO
|
||||
Console.WriteLine("Print something...");
|
||||
#endif
|
||||
|
||||
CheckSomething();
|
||||
|
||||
Console.WriteLine("End");
|
||||
|
||||
[Conditional("DEMO")]
|
||||
static void CheckSomething()
|
||||
{
|
||||
Console.WriteLine("Print from CheckSomething method");
|
||||
}
|
||||
|
||||
49
DefensiveProgramming/DefensiveProgramming.sln
Normal file
49
DefensiveProgramming/DefensiveProgramming.sln
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30413.136
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Barricades", "Barricades\Barricades.csproj", "{EC679AD5-7BC4-49E3-B44C-DB4750FBC179}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Conditional", "Conditional\Conditional.csproj", "{997943C5-5BA1-4BC4-A2C9-AAE0CA3BB934}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Using", "Using\Using.csproj", "{227D0323-D09C-44D5-B1CD-C2DD27CFC4DB}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Logging", "Logging\Logging.csproj", "{F7534F26-8855-4CA0-BEBC-C60ED2D1E7B1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Secrets", "Secrets\Secrets.csproj", "{78BFB6E2-A394-4CA1-A947-0CC2D8CDE421}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{EC679AD5-7BC4-49E3-B44C-DB4750FBC179}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EC679AD5-7BC4-49E3-B44C-DB4750FBC179}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EC679AD5-7BC4-49E3-B44C-DB4750FBC179}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EC679AD5-7BC4-49E3-B44C-DB4750FBC179}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{997943C5-5BA1-4BC4-A2C9-AAE0CA3BB934}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{997943C5-5BA1-4BC4-A2C9-AAE0CA3BB934}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{997943C5-5BA1-4BC4-A2C9-AAE0CA3BB934}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{997943C5-5BA1-4BC4-A2C9-AAE0CA3BB934}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{227D0323-D09C-44D5-B1CD-C2DD27CFC4DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{227D0323-D09C-44D5-B1CD-C2DD27CFC4DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{227D0323-D09C-44D5-B1CD-C2DD27CFC4DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{227D0323-D09C-44D5-B1CD-C2DD27CFC4DB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F7534F26-8855-4CA0-BEBC-C60ED2D1E7B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F7534F26-8855-4CA0-BEBC-C60ED2D1E7B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F7534F26-8855-4CA0-BEBC-C60ED2D1E7B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F7534F26-8855-4CA0-BEBC-C60ED2D1E7B1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{78BFB6E2-A394-4CA1-A947-0CC2D8CDE421}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{78BFB6E2-A394-4CA1-A947-0CC2D8CDE421}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{78BFB6E2-A394-4CA1-A947-0CC2D8CDE421}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{78BFB6E2-A394-4CA1-A947-0CC2D8CDE421}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {0C808F1C-DC45-4A56-8D42-13C593C59A78}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
60
DefensiveProgramming/Logging/DataLoader.cs
Normal file
60
DefensiveProgramming/Logging/DataLoader.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Logging;
|
||||
|
||||
public class DataLoader : IDataLoader
|
||||
{
|
||||
private readonly ILogger<DataLoader> logger;
|
||||
|
||||
public DataLoader(ILogger<DataLoader> logger)
|
||||
{
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public List<(string, DateOnly)> LoadData(string filename)
|
||||
{
|
||||
List<(string, DateOnly)> list = new();
|
||||
if (!File.Exists(filename))
|
||||
{
|
||||
string message = $"File {filename} does not exist";
|
||||
logger.LogError(message);
|
||||
throw new FileNotFoundException(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
//use File.ReadAllLines for small files
|
||||
using (var reader = new StreamReader(File.OpenRead(filename)))
|
||||
{
|
||||
string? line;
|
||||
while((line = reader.ReadLine()) != null) {
|
||||
string pattern = "[0-3]?[0-9].[0-3]?[0-9].[0-9]{4}.";
|
||||
var match = Regex.Match(line, pattern);
|
||||
if (match.Success)
|
||||
{
|
||||
string datetext = line.Substring(match.Index, match.Length);
|
||||
if (DateOnly.TryParseExact(datetext, "d.M.yyyy.", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateOnly date))
|
||||
{
|
||||
var item = (line.Remove(match.Index, match.Length).Trim(), date);
|
||||
logger.LogTrace(item.ToString());
|
||||
list.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogWarning("Invalid date in line: " + line);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogWarning("No date found in line: " + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
9
DefensiveProgramming/Logging/IDataLoader.cs
Normal file
9
DefensiveProgramming/Logging/IDataLoader.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Logging;
|
||||
|
||||
public interface IDataLoader
|
||||
{
|
||||
List<(string, DateOnly)> LoadData(string filename);
|
||||
}
|
||||
30
DefensiveProgramming/Logging/Logging.csproj
Normal file
30
DefensiveProgramming/Logging/Logging.csproj
Normal file
@@ -0,0 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.6" />
|
||||
<PackageReference Include="NLog" Version="6.1.2" />
|
||||
<PackageReference Include="NLog.Extensions.Logging" Version="6.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="data.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="nlog.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
45
DefensiveProgramming/Logging/Program.cs
Normal file
45
DefensiveProgramming/Logging/Program.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NLog.Extensions.Logging;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Logging;
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
using (var serviceProvider = BuildDI())
|
||||
{
|
||||
var dataLoader = serviceProvider.GetRequiredService<IDataLoader>();
|
||||
var list = dataLoader.LoadData("data.txt");
|
||||
var sortQuery = list.OrderByDescending(t => t.Item2)
|
||||
.ThenBy(t => t.Item1);
|
||||
|
||||
Console.WriteLine("Valid data: ");
|
||||
foreach (var item in sortQuery)
|
||||
{
|
||||
Console.WriteLine($"{item.Item2:yyyy-MM-dd} {item.Item1}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ServiceProvider BuildDI()
|
||||
{
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.AddJsonFile("appsettings.json")
|
||||
.Build();
|
||||
|
||||
IServiceCollection services = new ServiceCollection();
|
||||
var provider = services.AddLogging(configure => {
|
||||
configure.AddConfiguration(configuration.GetSection("Logging"));
|
||||
configure.AddConsole();
|
||||
configure.AddNLog(new NLogProviderOptions { RemoveLoggerFactoryFilter = false });
|
||||
})
|
||||
.AddTransient<IDataLoader, DataLoader>()
|
||||
.BuildServiceProvider();
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
9
DefensiveProgramming/Logging/appsettings.json
Normal file
9
DefensiveProgramming/Logging/appsettings.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Trace",
|
||||
"System": "Warning",
|
||||
"Microsoft": "Trace"
|
||||
}
|
||||
}
|
||||
}
|
||||
5
DefensiveProgramming/Logging/data.txt
Normal file
5
DefensiveProgramming/Logging/data.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Ana 22.5.1988.
|
||||
01.03.1995. Ivan John
|
||||
Ema
|
||||
Mario 15.13.1980.
|
||||
Klara 11.07.1998.
|
||||
31
DefensiveProgramming/Logging/nlog.config
Normal file
31
DefensiveProgramming/Logging/nlog.config
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
autoReload="true"
|
||||
internalLogLevel="Warn"
|
||||
internalLogFile="logs/internal-nlog.txt">
|
||||
|
||||
<!-- the targets to write to -->
|
||||
<targets>
|
||||
<!-- write logs to file -->
|
||||
<target xsi:type="File" name="allfile" fileName="logs/nlog-all-${shortdate}.log"
|
||||
layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${logger}|${uppercase:${level}}|${message} ${exception}" />
|
||||
|
||||
<!-- another file log, only own logs. Uses some ASP.NET core renderers -->
|
||||
<target xsi:type="File" name="ownFile" fileName="logs/nlog-own-${shortdate}.log"
|
||||
layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${logger}|${uppercase:${level}}| ${message} ${exception}" />
|
||||
|
||||
<!-- write to the void aka just remove -->
|
||||
<target xsi:type="Null" name="blackhole" />
|
||||
</targets>
|
||||
|
||||
<!-- rules to map from logger name to target -->
|
||||
<rules>
|
||||
<!--All logs, including from Microsoft-->
|
||||
<logger name="*" minlevel="Trace" writeTo="allfile" />
|
||||
|
||||
<!--Skip Microsoft logs and so log only own logs-->
|
||||
<logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" />
|
||||
<logger name="*" minlevel="Information" writeTo="ownFile" />
|
||||
</rules>
|
||||
</nlog>
|
||||
8
DefensiveProgramming/Secrets/Demo.cs
Normal file
8
DefensiveProgramming/Secrets/Demo.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Secrets;
|
||||
|
||||
public class Demo
|
||||
{
|
||||
public int Key0 { get; set; }
|
||||
public string? Key1 { get; set; }
|
||||
public string? Key2 { get; set; }
|
||||
}
|
||||
23
DefensiveProgramming/Secrets/Program.cs
Normal file
23
DefensiveProgramming/Secrets/Program.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Secrets;
|
||||
|
||||
var enumerator = Environment.GetEnvironmentVariables().GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
Console.WriteLine($"{enumerator.Key} = {enumerator.Value}");
|
||||
}
|
||||
Console.WriteLine("----------------------------");
|
||||
IConfiguration configuration = new ConfigurationBuilder()
|
||||
.AddJsonFile("appsettings.json") //order is important!
|
||||
.AddJsonFile("missing_one.json", optional: true) //
|
||||
.AddEnvironmentVariables() // include Package Microsoft.Extensions.Configuration.EnvironmentVariables
|
||||
.AddUserSecrets("PI-Secrets") //package Microsoft.Extensions.Configuration.UserSecrets
|
||||
.Build();
|
||||
|
||||
Console.WriteLine($"Custom env variable using configuration = " + configuration["CustomEnvValue"]);
|
||||
Console.WriteLine($"Name = " + configuration["Name"]);
|
||||
Console.WriteLine($"Key0 = " + configuration["Demo:Key0"]); //or Demo__Key0
|
||||
|
||||
Demo? demo = configuration.GetSection("Demo").Get<Demo>(); // package Microsoft.Extensions.Configuration.Binder
|
||||
Console.WriteLine($"Key1 = " + demo?.Key1);
|
||||
Console.WriteLine($"Key2 = " + demo?.Key2);
|
||||
10
DefensiveProgramming/Secrets/Properties/launchSettings.json
Normal file
10
DefensiveProgramming/Secrets/Properties/launchSettings.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"profiles": {
|
||||
"Secrets": {
|
||||
"commandName": "Project",
|
||||
"environmentVariables": {
|
||||
"CustomEnvValue": "Demo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
DefensiveProgramming/Secrets/Secrets.csproj
Normal file
23
DefensiveProgramming/Secrets/Secrets.csproj
Normal file
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<UserSecretsId>PI</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="10.0.6" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
7
DefensiveProgramming/Secrets/appsettings.json
Normal file
7
DefensiveProgramming/Secrets/appsettings.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"Name": "Bob",
|
||||
"Demo": {
|
||||
"Key0": 123,
|
||||
"Key1": "something that should not be publicly available"
|
||||
}
|
||||
}
|
||||
16
DefensiveProgramming/Using/C.cs
Normal file
16
DefensiveProgramming/Using/C.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
namespace Using;
|
||||
|
||||
class C : IDisposable
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public void Dispose()
|
||||
{
|
||||
Console.WriteLine("** {0} : Dispose **", Id);
|
||||
}
|
||||
|
||||
public C(string id)
|
||||
{
|
||||
Id = id;
|
||||
Console.WriteLine("----> {0} : Ctor", Id);
|
||||
}
|
||||
}
|
||||
20
DefensiveProgramming/Using/Program.cs
Normal file
20
DefensiveProgramming/Using/Program.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Using;
|
||||
|
||||
try
|
||||
{
|
||||
C a1 = new C("A1");
|
||||
|
||||
using (C b2 = new C("B2"))
|
||||
using (C d4 = new C("D4"))
|
||||
{
|
||||
C c3 = new C("C3");
|
||||
throw new Exception("It is time for an exception");
|
||||
}
|
||||
a1.Dispose();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Console.WriteLine("Exc: " + exc.Message);
|
||||
//throw exc;
|
||||
//throw;
|
||||
}
|
||||
10
DefensiveProgramming/Using/Using.csproj
Normal file
10
DefensiveProgramming/Using/Using.csproj
Normal file
@@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user