diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..105733c
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,246 @@
+# Remove the line below if you want to inherit .editorconfig settings from higher directories
+root = true
+
+# C# files
+[*.cs]
+
+#### Core EditorConfig Options ####
+
+# Indentation and spacing
+indent_size = 4
+indent_style = space
+tab_width = 4
+
+# New line preferences
+end_of_line = crlf
+insert_final_newline = false
+
+#### .NET Coding Conventions ####
+
+# Organize usings
+dotnet_separate_import_directive_groups = false
+dotnet_sort_system_directives_first = true
+file_header_template = unset
+
+# this. and Me. preferences
+dotnet_style_qualification_for_event = false
+dotnet_style_qualification_for_field = false
+dotnet_style_qualification_for_method = false
+dotnet_style_qualification_for_property = false
+
+# Language keywords vs BCL types preferences
+dotnet_style_predefined_type_for_locals_parameters_members = true
+dotnet_style_predefined_type_for_member_access = true
+
+# Parentheses preferences
+dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary
+dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary
+dotnet_style_parentheses_in_other_operators = never_if_unnecessary
+dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary
+
+# Modifier preferences
+dotnet_style_require_accessibility_modifiers = for_non_interface_members
+
+# Expression-level preferences
+dotnet_style_coalesce_expression = true
+dotnet_style_collection_initializer = true
+dotnet_style_explicit_tuple_names = true
+dotnet_style_namespace_match_folder = true
+dotnet_style_null_propagation = true
+dotnet_style_object_initializer = true
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+dotnet_style_prefer_auto_properties = true:warning
+dotnet_style_prefer_collection_expression = when_types_loosely_match
+dotnet_style_prefer_compound_assignment = true
+dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
+dotnet_style_prefer_conditional_expression_over_return = true:suggestion
+dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed
+dotnet_style_prefer_inferred_anonymous_type_member_names = true
+dotnet_style_prefer_inferred_tuple_names = true
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true
+dotnet_style_prefer_simplified_boolean_expressions = true
+dotnet_style_prefer_simplified_interpolation = true
+
+# Field preferences
+dotnet_style_readonly_field = true
+
+# Parameter preferences
+dotnet_code_quality_unused_parameters = all
+
+# Suppression preferences
+dotnet_remove_unnecessary_suppression_exclusions = none
+
+# New line preferences
+dotnet_style_allow_multiple_blank_lines_experimental = false
+dotnet_style_allow_statement_immediately_after_block_experimental = true
+
+#### C# Coding Conventions ####
+
+# var preferences
+csharp_style_var_elsewhere = false
+csharp_style_var_for_built_in_types = true
+csharp_style_var_when_type_is_apparent = true
+
+# Expression-bodied members
+csharp_style_expression_bodied_accessors = true:silent
+csharp_style_expression_bodied_constructors = true:silent
+csharp_style_expression_bodied_indexers = true:silent
+csharp_style_expression_bodied_lambdas = true:suggestion
+csharp_style_expression_bodied_local_functions = true:suggestion
+csharp_style_expression_bodied_methods = true:silent
+csharp_style_expression_bodied_operators = true:silent
+csharp_style_expression_bodied_properties = true:silent
+
+# Pattern matching preferences
+csharp_style_pattern_matching_over_as_with_null_check = true
+csharp_style_pattern_matching_over_is_with_cast_check = true
+csharp_style_prefer_extended_property_pattern = true
+csharp_style_prefer_not_pattern = true
+csharp_style_prefer_pattern_matching = true
+csharp_style_prefer_switch_expression = true
+
+# Null-checking preferences
+csharp_style_conditional_delegate_call = true
+
+# Modifier preferences
+csharp_prefer_static_local_function = true
+csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async
+csharp_style_prefer_readonly_struct = true
+csharp_style_prefer_readonly_struct_member = true
+
+# Code-block preferences
+csharp_prefer_braces = true:silent
+csharp_prefer_simple_using_statement = true:suggestion
+csharp_style_namespace_declarations = file_scoped:silent
+csharp_style_prefer_method_group_conversion = true:silent
+csharp_style_prefer_primary_constructors = true:suggestion
+csharp_style_prefer_top_level_statements = true:silent
+
+# Expression-level preferences
+csharp_prefer_simple_default_expression = true
+csharp_style_deconstructed_variable_declaration = true
+csharp_style_implicit_object_creation_when_type_is_apparent = true
+csharp_style_inlined_variable_declaration = true
+csharp_style_prefer_index_operator = true
+csharp_style_prefer_local_over_anonymous_function = true
+csharp_style_prefer_null_check_over_type_check = true
+csharp_style_prefer_range_operator = true
+csharp_style_prefer_tuple_swap = true
+csharp_style_prefer_utf8_string_literals = true
+csharp_style_throw_expression = true
+csharp_style_unused_value_assignment_preference = discard_variable:silent
+csharp_style_unused_value_expression_statement_preference = discard_variable
+
+# 'using' directive preferences
+csharp_using_directive_placement = outside_namespace:suggestion
+
+# New line preferences
+csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false
+csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true
+csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true
+csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
+csharp_style_allow_embedded_statements_on_same_line_experimental = true
+
+#### C# Formatting Rules ####
+
+# New line preferences
+csharp_new_line_before_catch = true
+csharp_new_line_before_else = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_open_brace = all
+csharp_new_line_between_query_expression_clauses = true
+
+# Indentation preferences
+csharp_indent_block_contents = true
+csharp_indent_braces = false
+csharp_indent_case_contents = true
+csharp_indent_case_contents_when_block = true
+csharp_indent_labels = one_less_than_current
+csharp_indent_switch_labels = true
+
+# Space preferences
+csharp_space_after_cast = false
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_after_comma = true
+csharp_space_after_dot = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_around_declaration_statements = false
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_before_comma = false
+csharp_space_before_dot = false
+csharp_space_before_open_square_brackets = false
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+csharp_space_between_square_brackets = false
+
+# Wrapping preferences
+csharp_preserve_single_line_blocks = true
+csharp_preserve_single_line_statements = true
+
+#### Naming styles ####
+
+# Naming rules
+
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+# Symbol specifications
+
+dotnet_naming_symbols.interface.applicable_kinds = interface
+dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.interface.required_modifiers =
+
+dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
+dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.types.required_modifiers =
+
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.non_field_members.required_modifiers =
+
+# Naming styles
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+
+dotnet_naming_style.begins_with_i.required_prefix = I
+dotnet_naming_style.begins_with_i.required_suffix =
+dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
+
+[*.{cs,vb}]
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+tab_width = 4
+indent_size = 4
+end_of_line = crlf
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
+dotnet_style_predefined_type_for_member_access = true:silent
+dotnet_style_require_accessibility_modifiers = omit_if_default:silent
+dotnet_style_qualification_for_field = false:silent
+dotnet_style_qualification_for_property = false:silent
+dotnet_style_qualification_for_method = false:silent
+dotnet_style_qualification_for_event = false:silent
\ No newline at end of file
diff --git a/Delegates.sln b/Delegates.sln
index f84c6e7..eb184a3 100644
--- a/Delegates.sln
+++ b/Delegates.sln
@@ -15,6 +15,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TitanicExplorer.Scripting",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TitanicExplorer.Scripting.Tests", "TitanicExplorer.Scripting.Tests\TitanicExplorer.Scripting.Tests.csproj", "{7D179EC1-554D-49D9-962D-D4C9CDE51A4C}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{452FAC10-9638-43FD-A3E0-A2D45AFEF1CD}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
diff --git a/Delegates/Delegates.csproj b/Delegates/Delegates.csproj
index 74abf5c..410fa2a 100644
--- a/Delegates/Delegates.csproj
+++ b/Delegates/Delegates.csproj
@@ -1,10 +1,10 @@
-
+
Exe
- net6.0
+ net8.0
enable
enable
-
+
diff --git a/Delegates/Guitar.cs b/Delegates/Guitar.cs
index a8b334b..593f0a2 100644
--- a/Delegates/Guitar.cs
+++ b/Delegates/Guitar.cs
@@ -1,55 +1,44 @@
-namespace Delegates
+namespace Delegates;
+
+///
+/// The pickup situation for the guitar
+///
+public enum PickupType
+{
+ Acoustic,
+ AcousticElectric,
+ Electric
+}
+
+///
+/// What kind of strings the guitar has
+///
+public enum StringType
+{
+ Steel,
+ Nylon
+}
+
+///
+/// Guitars because they're cool
+///
+/// The broad pickup type
+/// Steel string or nylon
+/// The name of the guitar
+public class Guitar(PickupType pickup, StringType strings, string name)
{
///
- /// The pickup situation for the guitar
+ /// Model Name of the guitar
///
- public enum PickupType
- {
- Acoustic,
- AcousticElectric,
- Electric
- }
+ public string Name { get; set; } = name;
///
- /// What kind of strings the guitar has
+ /// The pickup situation for the guitar
///
- public enum StringType
- {
- Steel,
- Nylon
- }
+ public PickupType Pickup { get; set; } = pickup;
///
- /// Guitars because they're cool
+ /// What kind of strings the guitar has
///
- public class Guitar
- {
- ///
- /// Constructor which sets all the properties
- ///
- /// The broad pickup type
- /// Steel string or nylon
- /// The name of the guitar
- public Guitar(PickupType pickup, StringType strings, string name)
- {
- Pickup = pickup;
- Strings = strings;
- Name = name;
- }
-
- ///
- /// Model Name of the guitar
- ///
- public string Name { get; set; }
-
- ///
- /// The pickup situation for the guitar
- ///
- public PickupType Pickup { get; set; }
-
- ///
- /// What kind of strings the guitar has
- ///
- public StringType Strings { get; set; }
- }
+ public StringType Strings { get; set; } = strings;
}
diff --git a/Delegates/Program.cs b/Delegates/Program.cs
index ddb3edc..db3c7e5 100644
--- a/Delegates/Program.cs
+++ b/Delegates/Program.cs
@@ -1,25 +1,23 @@
-using System;
-using System.Linq.Expressions;
+using System.Linq.Expressions;
-namespace Delegates
+namespace Delegates;
+
+static class Program
{
- internal class Program
+ static void Main()
{
- static void Main(string[] args)
- {
- var xExpression = Expression.Parameter(typeof(int), "x");
- var constantExpression = Expression.Constant(12);
- var greaterThan = Expression.GreaterThan(xExpression, constantExpression);
+ ParameterExpression xExpression = Expression.Parameter(typeof(int), "x");
+ ConstantExpression constantExpression = Expression.Constant(12);
+ BinaryExpression greaterThan = Expression.GreaterThan(xExpression, constantExpression);
- var constant4Expression = Expression.Constant(4);
- var lessThan = Expression.LessThan(xExpression, constant4Expression);
+ ConstantExpression constant4Expression = Expression.Constant(4);
+ BinaryExpression lessThan = Expression.LessThan(xExpression, constant4Expression);
- var or = Expression.Or(greaterThan, lessThan);
+ BinaryExpression or = Expression.Or(greaterThan, lessThan);
- var expr = Expression.Lambda>(or, false, new List { xExpression, });
- var func = expr.Compile();
+ var expr = Expression.Lambda>(or, false, new List { xExpression, });
+ Func func = expr.Compile();
- Console.WriteLine(func(2));
- }
+ Console.WriteLine(func(2));
}
}
\ No newline at end of file
diff --git a/TitanicExplorer.Data.Tests/DataTests.cs b/TitanicExplorer.Data.Tests/DataTests.cs
index ac48573..a8638d2 100644
--- a/TitanicExplorer.Data.Tests/DataTests.cs
+++ b/TitanicExplorer.Data.Tests/DataTests.cs
@@ -1,31 +1,26 @@
-namespace TitanicExplorer.Data.Tests
-{
- using Xunit;
- using System.IO;
- using System.Linq;
+using System.IO;
+using Xunit;
+
+namespace TitanicExplorer.Data.Tests;
- public class DataTests
+public class DataTests
+{
+ public DataTests()
{
- public DataTests()
- {
- this.SampleDataPath = Path.GetTempFileName();
+ SampleDataPath = Path.GetTempFileName();
- File.WriteAllText(this.SampleDataPath, Resource.passengers);
- }
+ File.WriteAllText(SampleDataPath, Resource.passengers);
+ }
- public string SampleDataPath
- {
- get; set;
- }
+ public string SampleDataPath { get; }
- [Fact]
- public void LoadData()
- {
- var passengers = Passenger.LoadFromFile(this.SampleDataPath);
+ [Fact]
+ public void LoadData()
+ {
+ System.Collections.Generic.List passengers = Passenger.LoadFromFile(SampleDataPath);
- Assert.Equal(887, passengers.Count());
+ Assert.Equal(887, passengers.Count);
- Assert.Equal("Mr. Owen Harris Braund", passengers.First().Name);
- }
+ Assert.Equal("Mr. Owen Harris Braund", passengers[0].Name);
}
}
\ No newline at end of file
diff --git a/TitanicExplorer.Data.Tests/TitanicExplorer.Data.Tests.csproj b/TitanicExplorer.Data.Tests/TitanicExplorer.Data.Tests.csproj
index 370efbf..2e25685 100644
--- a/TitanicExplorer.Data.Tests/TitanicExplorer.Data.Tests.csproj
+++ b/TitanicExplorer.Data.Tests/TitanicExplorer.Data.Tests.csproj
@@ -1,29 +1,28 @@
-
-
+
+
- net6.0
+ net8.0
enable
-
false
-
-
-
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
-
+
True
@@ -31,12 +30,12 @@
Resource.resx
-
+
ResXFileCodeGenerator
Resource.Designer.cs
-
+
diff --git a/TitanicExplorer.Data/Passenger.cs b/TitanicExplorer.Data/Passenger.cs
index a789a0f..0746bfd 100644
--- a/TitanicExplorer.Data/Passenger.cs
+++ b/TitanicExplorer.Data/Passenger.cs
@@ -1,48 +1,47 @@
-namespace TitanicExplorer.Data
+namespace TitanicExplorer.Data;
+
+public class Passenger
{
- public class Passenger
+ public enum SexValue
{
- public enum SexValue
- {
- Male = 0,
- Female = 1
- }
+ Male = 0,
+ Female = 1
+ }
- public bool Survived { get; set; }
- public int PClass { get; set; }
- public string Name { get; set; }
- public SexValue Sex { get; set; }
- public decimal Age { get;set; }
- public int SiblingsOrSpouse { get; set; }
- public int ParentOrChildren { get; set; }
- public decimal Fare { get; set; }
+ public bool Survived { get; set; }
+ public int PClass { get; set; }
+ public string Name { get; set; } = default!;
+ public SexValue Sex { get; set; }
+ public decimal Age { get; set; }
+ public int SiblingsOrSpouse { get; set; }
+ public int ParentOrChildren { get; set; }
+ public decimal Fare { get; set; }
- public static List LoadFromFile(string filePath)
- {
- var lines = File.ReadAllLines(filePath);
+ public static List LoadFromFile(string filePath)
+ {
+ var lines = File.ReadAllLines(filePath);
+
+ var passengers = new List();
- var passengers = new List();
+ foreach (var line in lines)
+ {
+ var values = line.Split('\t');
- foreach (var line in lines)
+ var passenger = new Passenger
{
- var values = line.Split('\t');
-
- var passenger = new Passenger
- {
- Survived = values[0] == "1",
- PClass = int.Parse(values[1]),
- Name = values[2],
- Sex = values[3] == "male" ? SexValue.Male : SexValue.Female,
- Age = decimal.Parse(values[4]),
- SiblingsOrSpouse = int.Parse(values[5]),
- ParentOrChildren = int.Parse(values[6]),
- Fare = decimal.Parse(values[7])
- };
-
- passengers.Add(passenger);
- }
-
- return passengers;
+ Survived = values[0] == "1",
+ PClass = int.Parse(values[1]),
+ Name = values[2],
+ Sex = values[3] == "male" ? SexValue.Male : SexValue.Female,
+ Age = decimal.Parse(values[4]),
+ SiblingsOrSpouse = int.Parse(values[5]),
+ ParentOrChildren = int.Parse(values[6]),
+ Fare = decimal.Parse(values[7])
+ };
+
+ passengers.Add(passenger);
}
+
+ return passengers;
}
}
\ No newline at end of file
diff --git a/TitanicExplorer.Data/TitanicExplorer.Data.csproj b/TitanicExplorer.Data/TitanicExplorer.Data.csproj
index 132c02c..9af4a6b 100644
--- a/TitanicExplorer.Data/TitanicExplorer.Data.csproj
+++ b/TitanicExplorer.Data/TitanicExplorer.Data.csproj
@@ -1,7 +1,7 @@
-
+
- net6.0
+ net8.0
enable
enable
diff --git a/TitanicExplorer.Scripting.Tests/TitanicExplorer.Scripting.Tests.csproj b/TitanicExplorer.Scripting.Tests/TitanicExplorer.Scripting.Tests.csproj
index 683961b..a172779 100644
--- a/TitanicExplorer.Scripting.Tests/TitanicExplorer.Scripting.Tests.csproj
+++ b/TitanicExplorer.Scripting.Tests/TitanicExplorer.Scripting.Tests.csproj
@@ -1,28 +1,27 @@
-
+
- net6.0
+ net8.0
enable
-
+
false
-
+
-
-
-
-
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
-
+
diff --git a/TitanicExplorer.Scripting.Tests/UnitTest1.cs b/TitanicExplorer.Scripting.Tests/UnitTest1.cs
index 9e4b76b..c2fc892 100644
--- a/TitanicExplorer.Scripting.Tests/UnitTest1.cs
+++ b/TitanicExplorer.Scripting.Tests/UnitTest1.cs
@@ -1,94 +1,85 @@
using System;
using System.Linq.Expressions;
-using TitanicExplorer.Scripting;
using Xunit;
-namespace TitanicExplorer.Scriptings.Tests
+namespace TitanicExplorer.Scripting.Tests;
+
+public class UnitTest1
{
- public class UnitTest1
+ [Fact]
+ public void IsPrimeTest()
{
- [Fact]
- public void IsPrime()
- {
- var value = Expression.Parameter(typeof(int), "value");
+ ParameterExpression value = Expression.Parameter(typeof(int), "value");
- var result = ScriptingEngine.IsPrime(value);
+ Expression result = ScriptingEngine.IsPrime(value);
- var expr = Expression.Lambda>(result, value);
+ var expr = Expression.Lambda>(result, value);
- var func = expr.Compile();
+ Func func = expr.Compile();
- Assert.False(func(0));
- Assert.False(func(1));
- Assert.True(func(2));
- Assert.True(func(3));
- Assert.False(func(4));
- Assert.True(func(5));
- Assert.False(func(9));
- Assert.False(func(144));
- Assert.True(func(1531));
- }
+ Assert.False(func(0));
+ Assert.False(func(1));
+ Assert.True(func(2));
+ Assert.True(func(3));
+ Assert.False(func(4));
+ Assert.True(func(5));
+ Assert.False(func(9));
+ Assert.False(func(144));
+ Assert.True(func(1531));
+ }
- [Fact]
- public void Test()
+ [Fact]
+ public void IsPrimeCSTest()
+ {
+ Assert.False(ScriptingEngine.IsPrimeCS(0));
+ Assert.False(ScriptingEngine.IsPrimeCS(1));
+ Assert.True(ScriptingEngine.IsPrimeCS(2));
+ Assert.True(ScriptingEngine.IsPrimeCS(3));
+ Assert.False(ScriptingEngine.IsPrimeCS(4));
+ Assert.True(ScriptingEngine.IsPrimeCS(5));
+ Assert.False(ScriptingEngine.IsPrimeCS(9));
+ Assert.False(ScriptingEngine.IsPrimeCS(144));
+ Assert.True(ScriptingEngine.IsPrimeCS(1531));
+ }
+
+ [Fact]
+ public void Test()
+ {
+ static bool func(int value)
{
- Func func = value =>
+ if (value <= 1) { return false; }
+
+ if (value <= 3) { return true; }
+
+ if (value % 2 == 0) { return false; }
+
+ var i = 3;
+ var boundary = (int)Math.Floor(Math.Sqrt(value));
+ while (i <= boundary)
{
- bool result;
-
- if (value <= 1)
- {
- return false;
- }
-
- if (value == 2)
- {
- return true;
- }
-
- if ((value % 2) == 0)
- {
- return false;
- }
-
- var i = 3;
- var boundary = (int)Math.Floor(Math.Sqrt((double)value));
- while (true)
- {
- if (i <= boundary)
- {
- if ((value % i) == 0)
- {
- return false;
- }
-
- i += 2;
- }
- else
- {
- break;
- }
- }
-
- return true;
- };
-
- Assert.True(func(19));
+ if (value % i == 0) { return false; }
+
+ i += 2;
+ }
+
+ return true;
}
- [Fact]
- public void Factorial()
- {
- var value = Expression.Parameter(typeof(int));
+ Assert.True(func(19));
+ }
+
+ [Fact]
+ public void Factorial()
+ {
+ ParameterExpression value = Expression.Parameter(typeof(int));
- var result = ScriptingEngine.Factorial(value);
+ Expression result = ScriptingEngine.Factorial(value);
- var expr = Expression.Lambda>(result, value);
+ var expr = Expression.Lambda>(result, value);
- var func = expr.Compile();
+ Func func = expr.Compile();
- Assert.Equal(6, func(3));
- Assert.Equal(120, func(5));
- }
+ Assert.Equal(6, func(3));
+ Assert.Equal(120, func(5));
}
}
\ No newline at end of file
diff --git a/TitanicExplorer.Scripting/ScriptingEngine.cs b/TitanicExplorer.Scripting/ScriptingEngine.cs
index d1ca23a..f78da83 100644
--- a/TitanicExplorer.Scripting/ScriptingEngine.cs
+++ b/TitanicExplorer.Scripting/ScriptingEngine.cs
@@ -1,114 +1,136 @@
-namespace TitanicExplorer.Scripting
-{
- using System.Linq.Dynamic.Core;
- using System.Linq.Expressions;
+using System.Linq.Dynamic.Core;
+using System.Linq.Expressions;
+
+namespace TitanicExplorer.Scripting;
- public class ScriptingEngine
+public static class ScriptingEngine
+{
+ public static Expression ExpressionFromString(string value) =>
+ DynamicExpressionParser.ParseLambda(new ParsingConfig(), true, value);
+
+ ///
+ /// C# high-level code to find if specified number is prime
+ ///
+ /// input parameter for testing if prime
+ /// true if number is prime, false otherwise
+ ///
+ /// 1. introduced at [4.10; 1:27] and in making-expression-trees-work-for-you-slides.pdf #25/37, but unfortunately absent in repo
+ /// - so featured here and unit-tested in TitanicExplorer.Scripting.Tests.UnitTest1.IsPrimeCSTest
+ /// 2. unfortunately all the juicy "Working with Roslyn" code is also absent [sigh]
+ /// 3. the short-circuit code tweaked slightly [yeah small-beer I know, but it goaded me], and ditto in IsPrime below
+ ///
+ public static bool IsPrimeCS(int number)
{
- public static Expression ExpressionFromString(string value)
- {
- return DynamicExpressionParser.ParseLambda(new ParsingConfig(), true, value);
- }
+ if (number <= 1) return false;
+ if (number <= 3) return true;
+ if (number % 2 == 0) return false;
- public static Expression IsPrime(ParameterExpression value)
+ var boundary = (int)Math.Floor(Math.Sqrt(number));
+ for (var i = 3; i <= boundary; i += 2)
{
- var label = Expression.Label();
-
- var result = Expression.Parameter(typeof(bool), "result");
-
- var returnLabel = Expression.Label(typeof(bool));
-
- var valueLessThanEqualToOne = Expression.LessThanOrEqual(value, Expression.Constant(1));
- var valueEqualTwo = Expression.Equal(value, Expression.Constant(2));
- var valueModTwoZero = Expression.Equal(Expression.Modulo(value, Expression.Constant(2)), Expression.Constant(0));
-
- var sqRt = typeof(Math).GetMethod("Sqrt");
- var floor = typeof(Math).GetMethod("Floor", new Type[] { typeof(double) });
-
- var valueSqRt = Expression.Call(null, sqRt, Expression.Convert(value, typeof(double)));
+ if (number % i == 0) { return false; }
+ }
+ return true;
+ }
- var evalFunction = Expression.Convert(Expression.Call(null, floor, valueSqRt), typeof(int));
+ public static Expression IsPrime(ParameterExpression value)
+ {
+ LabelTarget label = Expression.Label();
- var boundary = Expression.Variable(typeof(int), "boundary");
+ ParameterExpression result = Expression.Parameter(typeof(bool), "result");
- var i = Expression.Variable(typeof(int), "i");
+ LabelTarget returnLabel = Expression.Label(typeof(bool));
- Expression modBlock = Expression.IfThen(
- Expression.Equal(Expression.Modulo(value, i), Expression.Constant(0)),
- Expression.Return(returnLabel, Expression.Constant(false))
- );
+ BinaryExpression valueLessThanEqualToOne = Expression.LessThanOrEqual(value, Expression.Constant(1));
+ BinaryExpression valueLessThanEqualToThree = Expression.LessThanOrEqual(value, Expression.Constant(3));
+ BinaryExpression valueModTwoZero = Expression.Equal(Expression.Modulo(value, Expression.Constant(2)), Expression.Constant(0));
- Expression incrementI = Expression.AddAssign(i, Expression.Constant(2));
+ System.Reflection.MethodInfo sqRt = typeof(Math).GetMethod("Sqrt")!;
+ System.Reflection.MethodInfo floor = typeof(Math).GetMethod("Floor", [typeof(double)])!;
- BlockExpression block = Expression.Block(
- new[] { result, i, boundary },
- Expression.IfThen(
- valueLessThanEqualToOne,
- Expression.Return(returnLabel, Expression.Constant(false))
- ),
- Expression.IfThen(
- valueEqualTwo,
- Expression.Return(returnLabel, Expression.Constant(true))
- ),
- Expression.IfThen(
- valueModTwoZero,
- Expression.Return(returnLabel, Expression.Constant(false))
- ),
+ MethodCallExpression valueSqRt = Expression.Call(null, sqRt, Expression.Convert(value, typeof(double)));
- Expression.Assign(i, Expression.Constant(3)),
- Expression.Assign(boundary, evalFunction),
- Expression.Loop(
- Expression.IfThenElse
- (
- Expression.LessThanOrEqual(i, boundary),
- Expression.Block(modBlock, incrementI),
- Expression.Break(label)
- ),
- label
- ),
- Expression.Return(returnLabel, Expression.Constant(true)),
- Expression.Label(returnLabel, Expression.Constant(true))
- );
+ UnaryExpression evalFunction = Expression.Convert(Expression.Call(null, floor, valueSqRt), typeof(int));
- return block;
- }
+ ParameterExpression boundary = Expression.Variable(typeof(int), "boundary");
- ///
- /// From Microsoft Docs: https://docs.microsoft.com/en-us/dotnet/csharp/expression-trees-building
- ///
- /// Returns a factorial expression
- public static Expression Factorial(ParameterExpression value)
- {
- ParameterExpression result = Expression.Variable(typeof(int), "result");
+ ParameterExpression i = Expression.Variable(typeof(int), "i");
- // Creating a label that represents the return value
- LabelTarget label = Expression.Label(typeof(int));
+ Expression modBlock = Expression.IfThen(
+ Expression.Equal(Expression.Modulo(value, i), Expression.Constant(0)),
+ Expression.Return(returnLabel, Expression.Constant(false))
+ );
- var initializeResult = Expression.Assign(result, Expression.Constant(1));
+ Expression incrementI = Expression.AddAssign(i, Expression.Constant(2));
- // This is the inner block that performs the multiplication,
- // and decrements the value of 'n'
- var block = Expression.Block(
- Expression.Assign(result,
- Expression.Multiply(result, value)),
- Expression.PostDecrementAssign(value)
- );
+ BlockExpression block = Expression.Block(
+ [result, i, boundary],
+ Expression.IfThen(
+ valueLessThanEqualToOne,
+ Expression.Return(returnLabel, Expression.Constant(false))
+ ),
+ Expression.IfThen(
+ valueLessThanEqualToThree,
+ Expression.Return(returnLabel, Expression.Constant(true))
+ ),
+ Expression.IfThen(
+ valueModTwoZero,
+ Expression.Return(returnLabel, Expression.Constant(false))
+ ),
- // Creating a method body.
- BlockExpression body = Expression.Block(
- new[] { result },
- initializeResult,
+ Expression.Assign(i, Expression.Constant(3)),
+ Expression.Assign(boundary, evalFunction),
Expression.Loop(
- Expression.IfThenElse(
- Expression.GreaterThan(value, Expression.Constant(1)),
- block,
- Expression.Break(label, result)
+ Expression.IfThenElse
+ (
+ Expression.LessThanOrEqual(i, boundary),
+ Expression.Block(modBlock, incrementI),
+ Expression.Break(label)
),
label
- )
- );
+ ),
+ Expression.Return(returnLabel, Expression.Constant(true)),
+ Expression.Label(returnLabel, Expression.Constant(true))
+ );
- return body;
- }
+ return block;
+ }
+
+ ///
+ /// From Microsoft Docs: https://docs.microsoft.com/en-us/dotnet/csharp/expression-trees-building
+ ///
+ /// Returns a factorial expression
+ public static Expression Factorial(ParameterExpression value)
+ {
+ ParameterExpression result = Expression.Variable(typeof(int), "result");
+
+ // Creating a label that represents the return value
+ LabelTarget label = Expression.Label(typeof(int));
+
+ BinaryExpression initializeResult = Expression.Assign(result, Expression.Constant(1));
+
+ // This is the inner block that performs the multiplication,
+ // and decrements the value of 'n'
+ BlockExpression block = Expression.Block(
+ Expression.Assign(result,
+ Expression.Multiply(result, value)),
+ Expression.PostDecrementAssign(value)
+ );
+
+ // Creating a method body.
+ BlockExpression body = Expression.Block(
+ [result],
+ initializeResult,
+ Expression.Loop(
+ Expression.IfThenElse(
+ Expression.GreaterThan(value, Expression.Constant(1)),
+ block,
+ Expression.Break(label, result)
+ ),
+ label
+ )
+ );
+
+ return body;
}
}
\ No newline at end of file
diff --git a/TitanicExplorer.Scripting/TitanicExplorer.Scripting.csproj b/TitanicExplorer.Scripting/TitanicExplorer.Scripting.csproj
index 4e7adeb..b1dfbcb 100644
--- a/TitanicExplorer.Scripting/TitanicExplorer.Scripting.csproj
+++ b/TitanicExplorer.Scripting/TitanicExplorer.Scripting.csproj
@@ -1,13 +1,13 @@
-
-
+
+
- net6.0
+ net8.0
enable
enable
-
+
-
+
-
+
diff --git a/TitanicExplorer/Pages/Error.cshtml.cs b/TitanicExplorer/Pages/Error.cshtml.cs
index 59eed3f..a0292ce 100644
--- a/TitanicExplorer/Pages/Error.cshtml.cs
+++ b/TitanicExplorer/Pages/Error.cshtml.cs
@@ -1,27 +1,19 @@
+using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
-using System.Diagnostics;
-namespace TitanicExplorer.Pages
-{
- [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
- [IgnoreAntiforgeryToken]
- public class ErrorModel : PageModel
- {
- public string? RequestId { get; set; }
+namespace TitanicExplorer.Pages;
- public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
+[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
+[IgnoreAntiforgeryToken]
+public class ErrorModel(ILogger logger) : PageModel
+{
+ public string? RequestId { get; set; }
- private readonly ILogger _logger;
+ public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
- public ErrorModel(ILogger logger)
- {
- _logger = logger;
- }
+ public ILogger Logger => logger;
- public void OnGet()
- {
- RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
- }
- }
+ public void OnGet() =>
+ RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
\ No newline at end of file
diff --git a/TitanicExplorer/Pages/Index.cshtml b/TitanicExplorer/Pages/Index.cshtml
index 9c612e5..62785ab 100644
--- a/TitanicExplorer/Pages/Index.cshtml
+++ b/TitanicExplorer/Pages/Index.cshtml
@@ -66,7 +66,7 @@
-
+
diff --git a/TitanicExplorer/Pages/Index.cshtml.cs b/TitanicExplorer/Pages/Index.cshtml.cs
index 73a31cd..e3c12af 100644
--- a/TitanicExplorer/Pages/Index.cshtml.cs
+++ b/TitanicExplorer/Pages/Index.cshtml.cs
@@ -1,185 +1,145 @@
-namespace TitanicExplorer.Pages
+using System.Linq.Dynamic.Core;
+using System.Linq.Expressions;
+using AgileObjects.ReadableExpressions;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using TitanicExplorer.Data;
+using static TitanicExplorer.Data.Passenger;
+
+namespace TitanicExplorer.Pages;
+
+public class IndexModel : PageModel
{
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.AspNetCore.Mvc.RazorPages;
- using TitanicExplorer.Data;
- using System.IO;
- using static TitanicExplorer.Data.Passenger;
- using System.Linq.Expressions;
- using AgileObjects.ReadableExpressions;
- using System.Linq.Dynamic.Core;
-
- public class IndexModel : PageModel
+ public IndexModel(ILogger logger)
{
- private readonly ILogger _logger;
+ Logger = logger;
- public IndexModel(ILogger logger)
- {
- _logger = logger;
+ var sampleDataPath = Path.GetTempFileName();
- var sampleDataPath = Path.GetTempFileName();
+ System.IO.File.WriteAllText(sampleDataPath, DataFiles.passengers);
- System.IO.File.WriteAllText(sampleDataPath, DataFiles.passengers);
+ Passengers = Passenger.LoadFromFile(sampleDataPath);
+ }
+ public ILogger Logger { get; }
- this.Passengers = Passenger.LoadFromFile(sampleDataPath);
- }
+ public IEnumerable Passengers
+ {
+ get; private set;
+ }
- public IEnumerable Passengers
- {
- get; private set;
- }
+ public void OnGet()
+ { }
- public void OnGet()
- {
+ public string? Query { get; set; }
- }
-
- public string query { get; set; }
+ public void OnPost()
+ {
+ var survived = Request.Form["survived"] != "" ? ParseSurvived(Request.Form["survived"]!) : null;
+ var pClass = ParseNullInt(Request.Form["pClass"]!);
+ SexValue? sex = Request.Form["sex"] != "" ? ParseSex(Request.Form["sex"]!) : null;
+ var age = ParseNullDecimal(Request.Form["age"]!);
+ var minimumFare = ParseNullDecimal(Request.Form["minimumFare"]!);
+ Query = Request.Form["query"]!;
+
+ Passengers = FilterPassengers(survived, pClass, sex, age, minimumFare);
+ }
- public void OnPost()
- {
- var survived = Request.Form["survived"]!= "" ? ParseSurvived(Request.Form["survived"]) : null;
- var pClass = ParseNullInt(Request.Form["pClass"]);
- var sex = Request.Form["sex"] != "" ? ParseSex(Request.Form["sex"]) : null;
- var age = ParseNullDecimal(Request.Form["age"]);
- var minimumFare = ParseNullDecimal(Request.Form["minimumFare"]);
- this.query = Request.Form["query"];
-
- this.Passengers = FilterPassengers(survived, pClass, sex, age, minimumFare);
- }
+ IEnumerable FilterPassengers(bool? survived, int? pClass, SexValue? sex, decimal? age, decimal? minimumFare)
+ {
+ Expression? currentExpression = null;
- private IEnumerable FilterPassengers(bool? survived, int? pClass, SexValue? sex, decimal? age, decimal? minimumFare)
+ if (!string.IsNullOrEmpty(Query))
{
- Expression? currentExpression = null;
-
- if (!string.IsNullOrEmpty(this.query))
- {
- var expr = DynamicExpressionParser.ParseLambda(new ParsingConfig(), true, this.query);
-
- var func = expr.Compile();
-
- return this.Passengers.Where(func);
- }
-
- var passengerParameter = Expression.Parameter(typeof(Passenger));
+ Expression> expr = DynamicExpressionParser.ParseLambda(new ParsingConfig(), true, Query);
- if (survived != null)
- {
- currentExpression = CreateExpression(survived.Value, null, "Survived", passengerParameter);
- }
+ Func func = expr.Compile();
- if (pClass != null)
- {
- currentExpression = CreateExpression(pClass.Value, currentExpression, "PClass", passengerParameter);
- }
-
- if (sex != null)
- {
- currentExpression = CreateExpression(sex.Value, currentExpression, "Sex", passengerParameter);
- }
-
- if (age != null)
- {
- currentExpression = CreateExpression(age.Value, currentExpression, "Age", passengerParameter);
- }
-
- if (minimumFare != null)
- {
- currentExpression = CreateExpression(minimumFare.Value, currentExpression, "Fare", passengerParameter, ">");
- }
-
- if (currentExpression != null)
- {
- var expr = Expression.Lambda>(currentExpression, false, new List { passengerParameter });
- var func = expr.Compile();
-
- this.query = expr.ToReadableString();
+ return Passengers.Where(func);
+ }
- this.Passengers = this.Passengers.Where(func);
- }
+ ParameterExpression passengerParameter = Expression.Parameter(typeof(Passenger));
- return this.Passengers;
+ if (survived != null)
+ {
+ currentExpression = CreateExpression(survived.Value, null, "Survived", passengerParameter);
}
- ///
- /// Aggregates an expression with a property and an operator
- ///
- /// The type of the parameter
- /// The constant value to use in the expression
- /// The expression to aggregate with, if any
- /// The name of the property to call on the objectParameter
- /// The parameter for the object for evaluation
- /// A string of the operator to use
- ///
- private static Expression CreateExpression(T value, Expression? currentExpression, string propertyName, ParameterExpression objectParameter, string operatorType = "=")
+ if (pClass != null)
{
- var valueToTest = Expression.Constant(value);
-
- var propertyToCall = Expression.Property(objectParameter, propertyName);
-
- Expression operatorExpression;
-
- switch (operatorType)
- {
- case ">":
- operatorExpression = Expression.GreaterThan(propertyToCall, valueToTest);
- break;
- case "<":
- operatorExpression = Expression.LessThan(propertyToCall, valueToTest);
- break;
- case ">=":
- operatorExpression = Expression.GreaterThanOrEqual(propertyToCall, valueToTest);
- break;
- case "<=":
- operatorExpression = Expression.LessThanOrEqual(propertyToCall, valueToTest);
- break;
- default:
- operatorExpression = Expression.Equal(propertyToCall, valueToTest);
- break;
- }
-
- if (currentExpression == null)
- {
- currentExpression = operatorExpression;
- }
- else
- {
- var previousExpression = currentExpression;
-
- currentExpression = Expression.And(previousExpression, operatorExpression);
- }
-
- return currentExpression;
+ currentExpression = CreateExpression(pClass.Value, currentExpression, "PClass", passengerParameter);
}
- public decimal? ParseNullDecimal(string value)
+ if (sex != null)
{
- if (decimal.TryParse(value, out decimal result))
- {
- return result;
- }
-
- return null;
+ currentExpression = CreateExpression(sex.Value, currentExpression, "Sex", passengerParameter);
}
- public int? ParseNullInt(string value)
+ if (age != null)
{
- if (int.TryParse(value, out int result))
- {
- return result;
- }
-
- return null;
+ currentExpression = CreateExpression(age.Value, currentExpression, "Age", passengerParameter);
}
- public SexValue? ParseSex(string value)
+ if (minimumFare != null)
{
- return value == "male" ? SexValue.Male : SexValue.Female;
+ currentExpression = CreateExpression(minimumFare.Value, currentExpression, "Fare", passengerParameter, ">");
}
- public bool? ParseSurvived(string value)
+ if (currentExpression != null)
{
- return value == "Survived" ? true : false;
+ var expr = Expression.Lambda>(currentExpression, false, new List { passengerParameter });
+ Func func = expr.Compile();
+
+ Query = expr.ToReadableString();
+
+ Passengers = Passengers.Where(func);
}
+
+ return Passengers;
+ }
+
+ ///
+ /// Aggregates an expression with a property and an operator
+ ///
+ /// The type of the parameter
+ /// The constant value to use in the expression
+ /// The expression to aggregate with, if any
+ /// The name of the property to call on the objectParameter
+ /// The parameter for the object for evaluation
+ /// A string of the operator to use
+ ///
+ static Expression CreateExpression(T value, Expression? currentExpression, string propertyName, ParameterExpression objectParameter, string operatorType = "=")
+ {
+ ConstantExpression valueToTest = Expression.Constant(value);
+
+ MemberExpression propertyToCall = Expression.Property(objectParameter, propertyName);
+ Expression operatorExpression = operatorType switch
+ {
+ ">" => Expression.GreaterThan(propertyToCall, valueToTest),
+ "<" => Expression.LessThan(propertyToCall, valueToTest),
+ ">=" => Expression.GreaterThanOrEqual(propertyToCall, valueToTest),
+ "<=" => Expression.LessThanOrEqual(propertyToCall, valueToTest),
+ _ => Expression.Equal(propertyToCall, valueToTest),
+ };
+
+ return currentExpression == null
+ ? operatorExpression
+ : Expression.And(currentExpression, operatorExpression);
}
+
+ public decimal? ParseNullDecimal(string value) =>
+ decimal.TryParse(value, out var result)
+ ? result
+ : null;
+
+ public int? ParseNullInt(string value) =>
+ int.TryParse(value, out var result)
+ ? result
+ : null;
+
+ public SexValue? ParseSex(string value) =>
+ value == "male"
+ ? SexValue.Male
+ : SexValue.Female;
+
+ public bool? ParseSurvived(string value) =>
+ value == "Survived";
}
\ No newline at end of file
diff --git a/TitanicExplorer/Pages/Privacy.cshtml.cs b/TitanicExplorer/Pages/Privacy.cshtml.cs
index 1f05d19..887ed1d 100644
--- a/TitanicExplorer/Pages/Privacy.cshtml.cs
+++ b/TitanicExplorer/Pages/Privacy.cshtml.cs
@@ -1,19 +1,11 @@
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Mvc.RazorPages;
+using Microsoft.AspNetCore.Mvc.RazorPages;
-namespace TitanicExplorer.Pages
-{
- public class PrivacyModel : PageModel
- {
- private readonly ILogger _logger;
+namespace TitanicExplorer.Pages;
- public PrivacyModel(ILogger logger)
- {
- _logger = logger;
- }
+public class PrivacyModel(ILogger logger) : PageModel
+{
+ public ILogger Logger => logger;
- public void OnGet()
- {
- }
- }
+ public void OnGet()
+ { }
}
\ No newline at end of file
diff --git a/TitanicExplorer/Program.cs b/TitanicExplorer/Program.cs
index bc275e4..3530326 100644
--- a/TitanicExplorer/Program.cs
+++ b/TitanicExplorer/Program.cs
@@ -1,16 +1,16 @@
-var builder = WebApplication.CreateBuilder(args);
+WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
-var app = builder.Build();
+WebApplication app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
- app.UseExceptionHandler("/Error");
+ _ = app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
- app.UseHsts();
+ _ = app.UseHsts();
}
app.UseHttpsRedirection();
diff --git a/TitanicExplorer/TitanicExplorer.csproj b/TitanicExplorer/TitanicExplorer.csproj
index 23119ae..017d2ad 100644
--- a/TitanicExplorer/TitanicExplorer.csproj
+++ b/TitanicExplorer/TitanicExplorer.csproj
@@ -1,14 +1,14 @@
-
+
- net6.0
+ net8.0
enable
enable
-
-
+
+