diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index f76aad0b8e204ddad3a675375bd5be6cc73eed8b..0000000000000000000000000000000000000000
--- a/.editorconfig
+++ /dev/null
@@ -1,225 +0,0 @@
-# 如果要从更高级别的目录继承 .editorconfig 设置,请删除以下行
-root = true
-
-# c# 文件
-[*.cs]
-
-#### Core EditorConfig 选项 ####
-
-# 缩进和间距
-indent_size = 4
-indent_style = space
-tab_width = 4
-
-# 新行首选项
-end_of_line = crlf
-insert_final_newline = false
-
-#### .NET 编码约定 ####
-
-# 组织 Using
-dotnet_separate_import_directive_groups = false
-dotnet_sort_system_directives_first = false
-file_header_template = unset
-
-# this. 和 Me. 首选项
-dotnet_style_qualification_for_event = false
-dotnet_style_qualification_for_field = false
-dotnet_style_qualification_for_method = false
-dotnet_style_qualification_for_property = false
-
-# 语言关键字与 bcl 类型首选项
-dotnet_style_predefined_type_for_locals_parameters_members = true
-dotnet_style_predefined_type_for_member_access = true
-
-# 括号首选项
-dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
-dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
-dotnet_style_parentheses_in_other_operators = never_if_unnecessary
-dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
-
-# 修饰符首选项
-dotnet_style_require_accessibility_modifiers = for_non_interface_members
-
-# 表达式级首选项
-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
-dotnet_style_prefer_compound_assignment = true
-dotnet_style_prefer_conditional_expression_over_assignment = true
-dotnet_style_prefer_conditional_expression_over_return = true
-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:error
-dotnet_style_prefer_simplified_boolean_expressions = true
-dotnet_style_prefer_simplified_interpolation = true
-
-# 字段首选项
-dotnet_style_readonly_field = true
-
-# 参数首选项
-dotnet_code_quality_unused_parameters = all
-
-# 禁止显示首选项
-dotnet_remove_unnecessary_suppression_exclusions = 0
-
-# 新行首选项
-dotnet_style_allow_multiple_blank_lines_experimental = true
-dotnet_style_allow_statement_immediately_after_block_experimental = true
-
-#### c# 编码约定 ####
-
-# var 首选项
-csharp_style_var_elsewhere = false
-csharp_style_var_for_built_in_types = false
-csharp_style_var_when_type_is_apparent = false
-
-# Expression-bodied 成员
-csharp_style_expression_bodied_accessors = true
-csharp_style_expression_bodied_constructors = false
-csharp_style_expression_bodied_indexers = true
-csharp_style_expression_bodied_lambdas = true
-csharp_style_expression_bodied_local_functions = false
-csharp_style_expression_bodied_methods = false
-csharp_style_expression_bodied_operators = false
-csharp_style_expression_bodied_properties = true
-
-# 模式匹配首选项
-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 检查首选项
-csharp_style_conditional_delegate_call = true
-
-# 修饰符首选项
-csharp_prefer_static_local_function = true
-csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
-
-# 代码块首选项
-csharp_prefer_braces = true
-csharp_prefer_simple_using_statement = true
-csharp_style_namespace_declarations = block_scoped
-csharp_style_prefer_method_group_conversion = true
-csharp_style_prefer_top_level_statements = true
-
-# 表达式级首选项
-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
-csharp_style_unused_value_expression_statement_preference = discard_variable
-
-# "using" 指令首选项
-csharp_using_directive_placement = outside_namespace
-
-# 新行首选项
-csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
-csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true
-csharp_style_allow_embedded_statements_on_same_line_experimental = true
-
-#### C# 格式规则 ####
-
-# 新行首选项
-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 = accessors,anonymous_methods,anonymous_types,control_blocks,methods,object_collection_array_initializers,properties,types
-csharp_new_line_between_query_expression_clauses = true
-
-# 缩进首选项
-csharp_indent_block_contents = true
-csharp_indent_braces = false
-csharp_indent_case_contents = false
-csharp_indent_case_contents_when_block = false
-csharp_indent_labels = one_less_than_current
-csharp_indent_switch_labels = true
-
-# 空格键首选项
-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
-
-# 包装首选项
-csharp_preserve_single_line_blocks = true
-csharp_preserve_single_line_statements = true
-
-#### 命名样式 ####
-
-# 命名规则
-
-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
-
-# 符号规范
-
-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 =
-
-# 命名样式
-
-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
diff --git a/.gitignore b/.gitignore
index e910608fc1ecabe29cb4e88eeab0a35a2b752e7d..75cf7609c93112bc84a2b63eca3f0089dec77a45 100644
--- a/.gitignore
+++ b/.gitignore
@@ -407,4 +407,4 @@ healthchecksdb
.vscode
#ifoxcad
-#tests/TestConsole/
\ No newline at end of file
+**/Properties/launchSettings.json
diff --git a/IFoxCAD.sln b/IFoxCAD.sln
index 802ff1cc56ccadea875f242dea64a2a32a0c0d69..8b9d772194969843ac6842ac33ccc16608fb0f74 100644
--- a/IFoxCAD.sln
+++ b/IFoxCAD.sln
@@ -1,137 +1,71 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
-VisualStudioVersion = 17.1.32113.165
+VisualStudioVersion = 17.8.34309.116
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Config", "Config", "{786E7347-B116-4F26-9AEF-33EB0AB88D58}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{AE09C3B7-58AC-4A68-9884-1F93FDA5D785}"
ProjectSection(SolutionItems) = preProject
- .editorconfig = .editorconfig
- .gitattributes = .gitattributes
- .gitignore = .gitignore
+ src\Directory.Build.props = src\Directory.Build.props
EndProjectSection
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestConsole", "tests\TestConsole\TestConsole.csproj", "{E2873F0B-CAD2-45E8-8FF0-C05C0C6AD955}"
+Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CADShared", "src\CADShared\CADShared.shproj", "{5178502E-9A78-4588-B849-33ED439976B2}"
EndProject
-Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "TestShared", "tests\TestShared\TestShared.shproj", "{CED63D2D-0AF6-4831-806D-5E8E9B0D0A07}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestAcad09plus", "tests\TestAcad09plus\TestAcad09plus.csproj", "{5F478F68-19BC-4A3A-AF39-8728F8D396DD}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{C0BEFC15-6DF7-4636-BC76-4A0B88231470}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Basal", "Basal", "{1A5C27C1-FEF3-40A0-A1EE-3BC7BF2BD67A}"
- ProjectSection(SolutionItems) = preProject
- src\Basal\Directory.Build.props = src\Basal\Directory.Build.props
- EndProjectSection
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IFoxCAD.AutoCad", "src\IFoxCAD.AutoCad\IFoxCAD.AutoCad.csproj", "{9A0A144F-6820-4D15-9D39-43B7298195E3}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IFox.Basal", "src\Basal\IFox.Basal\IFox.Basal.csproj", "{FF4E1CDE-EEB3-4BE8-8C1D-6B5B17A299C7}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IFoxCAD.ZwCad", "src\IFoxCAD.ZwCad\IFoxCAD.ZwCad.csproj", "{8546C2AC-815C-47A1-9D8C-A6470DF44AD9}"
EndProject
-Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "IFox.Basal.Shared", "src\Basal\IFox.Basal.Shared\IFox.Basal.Shared.shproj", "{C823514A-2BC2-45C2-ACED-18924A7B80BF}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{46F3EDA8-A6D1-4707-8D03-731CADB41A56}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IFox.Basal.Source", "src\Basal\IFox.Basal.Source\IFox.Basal.Source.csproj", "{D0C6824C-53A3-4C16-AE7B-3227F18C5039}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestAcad2025", "tests\TestAcad2025\TestAcad2025.csproj", "{47C42AB4-C2F4-475B-899C-71FDE57D926E}"
EndProject
-Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "IFox.CAD.Shared", "src\CAD\IFox.CAD.Shared\IFox.CAD.Shared.shproj", "{20F254F7-AEE5-42AE-A9B3-149BBDC7397F}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestZcad2025", "tests\TestZcad2025\TestZcad2025.csproj", "{0B4601B4-CBDA-4FD8-9B31-C1E292D03068}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CAD", "CAD", "{B2AB7DC7-DBF4-4197-808B-0D2A6613AF5E}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{7145708C-A65B-470E-A8DA-ED79AC9A42D7}"
ProjectSection(SolutionItems) = preProject
- src\CAD\Directory.Build.props = src\CAD\Directory.Build.props
- EndProjectSection
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IFox.CAD.Source", "src\CAD\IFox.CAD.Source\IFox.CAD.Source.csproj", "{88F3CF78-23F5-494B-9D8F-2C6B4467E0B4}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IFox.CAD.ACAD", "src\CAD\IFox.CAD.ACAD\IFox.CAD.ACAD.csproj", "{EF20E632-70A9-40EB-8C9A-539FD85FAFAD}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IFox.CAD.GCAD", "src\CAD\IFox.CAD.GCAD\IFox.CAD.GCAD.csproj", "{F388F4B9-F636-414A-9BC9-2B008517B441}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IFox.CAD.ZCAD", "src\CAD\IFox.CAD.ZCAD\IFox.CAD.ZCAD.csproj", "{3D7D095D-EF0A-40B3-9776-5F08C61FD614}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WPF", "WPF", "{1EE1F817-39D3-43E5-B087-E7AD4D0BEC93}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IFox.WPF", "src\WPF\IFox.WPF.csproj", "{6ED0A677-6621-4493-AF58-71C2BF31DFCE}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{DA8EA8E7-A98E-4565-A3BF-97855988DB8E}"
- ProjectSection(SolutionItems) = preProject
- docs\0x01代码规范.md = docs\0x01代码规范.md
- docs\DBTrans.md = docs\DBTrans.md
- LICENSE = LICENSE
- README.md = README.md
- docs\SelectionFilter.md = docs\SelectionFilter.md
- docs\SymbolTable.md = docs\SymbolTable.md
- docs\WPF.md = docs\WPF.md
docs\关于IFoxCAD的架构说明.md = docs\关于IFoxCAD的架构说明.md
- docs\关于扩展函数的说明.md = docs\关于扩展函数的说明.md
EndProjectSection
EndProject
+Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "TestShared", "tests\TestShared\TestShared.shproj", "{CED63D2D-0AF6-4831-806D-5E8E9B0D0A07}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {E2873F0B-CAD2-45E8-8FF0-C05C0C6AD955}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E2873F0B-CAD2-45E8-8FF0-C05C0C6AD955}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E2873F0B-CAD2-45E8-8FF0-C05C0C6AD955}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E2873F0B-CAD2-45E8-8FF0-C05C0C6AD955}.Release|Any CPU.Build.0 = Release|Any CPU
- {5F478F68-19BC-4A3A-AF39-8728F8D396DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {5F478F68-19BC-4A3A-AF39-8728F8D396DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {5F478F68-19BC-4A3A-AF39-8728F8D396DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {5F478F68-19BC-4A3A-AF39-8728F8D396DD}.Release|Any CPU.Build.0 = Release|Any CPU
- {FF4E1CDE-EEB3-4BE8-8C1D-6B5B17A299C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {FF4E1CDE-EEB3-4BE8-8C1D-6B5B17A299C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {FF4E1CDE-EEB3-4BE8-8C1D-6B5B17A299C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {FF4E1CDE-EEB3-4BE8-8C1D-6B5B17A299C7}.Release|Any CPU.Build.0 = Release|Any CPU
- {D0C6824C-53A3-4C16-AE7B-3227F18C5039}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D0C6824C-53A3-4C16-AE7B-3227F18C5039}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D0C6824C-53A3-4C16-AE7B-3227F18C5039}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D0C6824C-53A3-4C16-AE7B-3227F18C5039}.Release|Any CPU.Build.0 = Release|Any CPU
- {88F3CF78-23F5-494B-9D8F-2C6B4467E0B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {88F3CF78-23F5-494B-9D8F-2C6B4467E0B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {88F3CF78-23F5-494B-9D8F-2C6B4467E0B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {88F3CF78-23F5-494B-9D8F-2C6B4467E0B4}.Release|Any CPU.Build.0 = Release|Any CPU
- {EF20E632-70A9-40EB-8C9A-539FD85FAFAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {EF20E632-70A9-40EB-8C9A-539FD85FAFAD}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {EF20E632-70A9-40EB-8C9A-539FD85FAFAD}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {EF20E632-70A9-40EB-8C9A-539FD85FAFAD}.Release|Any CPU.Build.0 = Release|Any CPU
- {F388F4B9-F636-414A-9BC9-2B008517B441}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F388F4B9-F636-414A-9BC9-2B008517B441}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F388F4B9-F636-414A-9BC9-2B008517B441}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F388F4B9-F636-414A-9BC9-2B008517B441}.Release|Any CPU.Build.0 = Release|Any CPU
- {3D7D095D-EF0A-40B3-9776-5F08C61FD614}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {3D7D095D-EF0A-40B3-9776-5F08C61FD614}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {3D7D095D-EF0A-40B3-9776-5F08C61FD614}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {3D7D095D-EF0A-40B3-9776-5F08C61FD614}.Release|Any CPU.Build.0 = Release|Any CPU
- {6ED0A677-6621-4493-AF58-71C2BF31DFCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6ED0A677-6621-4493-AF58-71C2BF31DFCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6ED0A677-6621-4493-AF58-71C2BF31DFCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6ED0A677-6621-4493-AF58-71C2BF31DFCE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9A0A144F-6820-4D15-9D39-43B7298195E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9A0A144F-6820-4D15-9D39-43B7298195E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9A0A144F-6820-4D15-9D39-43B7298195E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9A0A144F-6820-4D15-9D39-43B7298195E3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8546C2AC-815C-47A1-9D8C-A6470DF44AD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8546C2AC-815C-47A1-9D8C-A6470DF44AD9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8546C2AC-815C-47A1-9D8C-A6470DF44AD9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8546C2AC-815C-47A1-9D8C-A6470DF44AD9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {47C42AB4-C2F4-475B-899C-71FDE57D926E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {47C42AB4-C2F4-475B-899C-71FDE57D926E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {47C42AB4-C2F4-475B-899C-71FDE57D926E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {47C42AB4-C2F4-475B-899C-71FDE57D926E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0B4601B4-CBDA-4FD8-9B31-C1E292D03068}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0B4601B4-CBDA-4FD8-9B31-C1E292D03068}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0B4601B4-CBDA-4FD8-9B31-C1E292D03068}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0B4601B4-CBDA-4FD8-9B31-C1E292D03068}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {E2873F0B-CAD2-45E8-8FF0-C05C0C6AD955} = {C0BEFC15-6DF7-4636-BC76-4A0B88231470}
- {CED63D2D-0AF6-4831-806D-5E8E9B0D0A07} = {C0BEFC15-6DF7-4636-BC76-4A0B88231470}
- {5F478F68-19BC-4A3A-AF39-8728F8D396DD} = {C0BEFC15-6DF7-4636-BC76-4A0B88231470}
- {FF4E1CDE-EEB3-4BE8-8C1D-6B5B17A299C7} = {1A5C27C1-FEF3-40A0-A1EE-3BC7BF2BD67A}
- {C823514A-2BC2-45C2-ACED-18924A7B80BF} = {1A5C27C1-FEF3-40A0-A1EE-3BC7BF2BD67A}
- {D0C6824C-53A3-4C16-AE7B-3227F18C5039} = {1A5C27C1-FEF3-40A0-A1EE-3BC7BF2BD67A}
- {20F254F7-AEE5-42AE-A9B3-149BBDC7397F} = {B2AB7DC7-DBF4-4197-808B-0D2A6613AF5E}
- {88F3CF78-23F5-494B-9D8F-2C6B4467E0B4} = {B2AB7DC7-DBF4-4197-808B-0D2A6613AF5E}
- {EF20E632-70A9-40EB-8C9A-539FD85FAFAD} = {B2AB7DC7-DBF4-4197-808B-0D2A6613AF5E}
- {F388F4B9-F636-414A-9BC9-2B008517B441} = {B2AB7DC7-DBF4-4197-808B-0D2A6613AF5E}
- {3D7D095D-EF0A-40B3-9776-5F08C61FD614} = {B2AB7DC7-DBF4-4197-808B-0D2A6613AF5E}
- {6ED0A677-6621-4493-AF58-71C2BF31DFCE} = {1EE1F817-39D3-43E5-B087-E7AD4D0BEC93}
- EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {31D6C754-CF6B-4AB0-9861-6923DD312350}
+ SolutionGuid = {57CA0128-08DE-436F-B9F1-82C64F49BF67}
EndGlobalSection
GlobalSection(SharedMSBuildProjectFiles) = preSolution
- src\CAD\IFox.CAD.Shared\IFox.CAD.Shared.projitems*{20f254f7-aee5-42ae-a9b3-149bbdc7397f}*SharedItemsImports = 13
- src\CAD\IFox.CAD.Shared\IFox.CAD.Shared.projitems*{3d7d095d-ef0a-40b3-9776-5f08c61fd614}*SharedItemsImports = 5
- tests\TestShared\TestShared.projitems*{5f478f68-19bc-4a3a-af39-8728f8d396dd}*SharedItemsImports = 5
- src\Basal\IFox.Basal.Shared\IFox.Basal.Shared.projitems*{c823514a-2bc2-45c2-aced-18924a7b80bf}*SharedItemsImports = 13
- tests\TestShared\TestShared.projitems*{ced63d2d-0af6-4831-806d-5e8e9b0d0a07}*SharedItemsImports = 13
- src\CAD\IFox.CAD.Shared\IFox.CAD.Shared.projitems*{ef20e632-70a9-40eb-8c9a-539fd85fafad}*SharedItemsImports = 5
- src\CAD\IFox.CAD.Shared\IFox.CAD.Shared.projitems*{f388f4b9-f636-414a-9bc9-2b008517b441}*SharedItemsImports = 5
- src\Basal\IFox.Basal.Shared\IFox.Basal.Shared.projitems*{ff4e1cde-eeb3-4be8-8c1d-6b5b17a299c7}*SharedItemsImports = 5
+ CADShared\CADShared.projitems*{5178502e-9a78-4588-b849-33ed439976b2}*SharedItemsImports = 13
+ CADShared\CADShared.projitems*{6b29955a-5796-4035-9297-210fa15d3846}*SharedItemsImports = 5
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {9A0A144F-6820-4D15-9D39-43B7298195E3} = {AE09C3B7-58AC-4A68-9884-1F93FDA5D785}
+ {8546C2AC-815C-47A1-9D8C-A6470DF44AD9} = {AE09C3B7-58AC-4A68-9884-1F93FDA5D785}
+ {47C42AB4-C2F4-475B-899C-71FDE57D926E} = {46F3EDA8-A6D1-4707-8D03-731CADB41A56}
+ {0B4601B4-CBDA-4FD8-9B31-C1E292D03068} = {46F3EDA8-A6D1-4707-8D03-731CADB41A56}
+ {CED63D2D-0AF6-4831-806D-5E8E9B0D0A07} = {46F3EDA8-A6D1-4707-8D03-731CADB41A56}
+ {5178502E-9A78-4588-B849-33ED439976B2} = {AE09C3B7-58AC-4A68-9884-1F93FDA5D785}
EndGlobalSection
EndGlobal
diff --git a/IFoxCAD.sln.DotSettings b/IFoxCAD.sln.DotSettings
new file mode 100644
index 0000000000000000000000000000000000000000..6b05d846b2d8da01c18f95eea13cb8da1ea097f4
--- /dev/null
+++ b/IFoxCAD.sln.DotSettings
@@ -0,0 +1,32 @@
+
+ API
+ DB
+ OS
+ SS
+ WMF
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
\ No newline at end of file
diff --git a/README.md b/README.md
deleted file mode 100644
index c29b07b76f66a8749a9effdd513d4cdc71b69bc3..0000000000000000000000000000000000000000
--- a/README.md
+++ /dev/null
@@ -1,176 +0,0 @@
-# IFoxCAD 说明
-
-基于.NET的Cad二次开发类库。
-
-#### 一、项目来源
-
-起初 **雪山飞狐(又狐哥)** 在明经论坛发布了[开源库](http://bbs.mjtd.com/thread-75701-1-1.html),后来狐哥自己的项目进行了极大的丰富后形成NFox类库。然后 **落魄山人** 在征得 雪山飞狐的同意后,对NFox类库进行了整理,增加了注释等,重新发布了NFox类库。
-
-后来,经过一段时间的更新后,由于莫名其妙的原因NFox类库挂掉了。而这时山人同学已经基本吃透NFox类库,考虑到NFox的封装过于复杂,遂进行了重构。
-
-重构的类库命名为IFoxCAD, 寓意为:**I(爱)Fox(狐哥)**,本项目发布于**Inspire Function(中文名:跃动方程)** 组织下,感谢 **小轩轩** 给起的名字。
-
-可以加群交流:
-
-
-
-#### 二、 快速入门
-
-- 打开vs,新建一个standard类型的类库项目,**注意,需要选择类型的时候一定要选standard2.0**
-
-- 双击项目,打开项目文件:
-
- - 修改项目文件里的`netcore2.0`为`NET45`。其中的net45,可以改为NET45以上的标准TFM(如:net45、net46、net47等等)。同时可以指定多版本。具体的详细的教程见 [VS通过添加不同引用库,建立多条件编译](https://www.yuque.com/vicwjb/zqpcd0/ufbwyl)。
-
- - 在 ` xxx ` 中增加 `preview`,主要是为了支持最新的语法,本项目采用了最新的语法编写。项目文件现在的内容类似如下:
-
-```xml
-
-
- net45
- preview
-
-
-```
-
-- 右键项目文件,选择管理nuget程序包。
-
-- 在nuget程序里搜索**ifox**,记得将包括预发行版打钩。截止本文最后更新时,nuget上最新的版本为ifox.cad.source 0.5.2.1版本和ifox.Basal.source 0.5.2.3版本。点击安装就可以。
-
-- 添加引用,在新建的项目里的cs文件里添加相关的引用
-
-```csharp
-using Autodesk.AutoCAD.ApplicationServices;
-using Autodesk.AutoCAD.EditorInput;
-using Autodesk.AutoCAD.Runtime;
-using Autodesk.AutoCAD.Geometry;
-using Autodesk.AutoCAD.DatabaseServices;
-using IFoxCAD.Cad;
-```
-
-- 添加代码
-
-```csharp
-[CommandMethod(nameof(Hello))]
-public void Hello()
-{
- using DBTrans tr = new();
- var line1 = new Line(new Point3d(0, 0, 0), new Point3d(1, 1, 0));
- tr.CurrentSpace.AddEntity(line1);
- // 如果您没有添加preview到项目文件里的话:按如下旧语法:
- // using(var tr = new DBTrans())
- // {
- // var line1 = new Line(new Point3d(0, 0, 0), new Point3d(1, 1, 0));
- // tr.CurrentSpace.AddEntity(line1);
- // }
-}
-```
-
-这段代码就是在cad的当前空间内添加了一条直线。
-
-- 生成,然后打开cad,netload命令将刚刚生成的dll加载。如果需要调试需要设置启动程序为cad。
-
-- 运行hello命令,然后缩放一下视图,现在一条直线和一个圆已经显示在屏幕上了
-
-#### 三、屏蔽IFox的元组、索引、范围功能
-
-特别提醒: 考虑到早期的框架没有提供System.Range类型(net core 开始提供)、System.Index类型(net core 开始提供)、System.ValueTuple类型(net 47开始提供),本项目IFox.Basal包里包含了他们。 如果引用了包含System.Range等类型的第三方包(如IndexRange等),请在项目文件中定义NOINDEX、NORANGE、NOVALUETUPLE常量,以避免重复定义。上述代码能起作用的前提是用源码包,普通包暂时无解。
-
-```xml
-
- $(Configuration);NOINDEX;NORANGE;NOVALUETUPLE
-
-```
-
-**NOINDEX、NORANGE、NOVALUETUPLE 分别针对三种类型,哪种类型冲突就定义哪种。**
-
-#### 四、编译 IFox 源码工程
-
-由于vs2022抛弃了某几个net版本,所以我们同时安装vs2019和vs2022,然后使用vs2022;
-其中的原因是vs2019拥有全部net版本,而vs2022拥有最新的分析器和语法。
-
-编译本项目需要你准备好git,具体的安装教程可以去网上搜索一下。当然也可以利用vs的git来完成。
-
-首先在gitee上fork本项目到你的账号,然后clone到本地。
-
-原生git使用命令行,打开终端/powershell/cmd,cd到你要存放的目录,然后运行下面的命令,把里面的yourname替换为你的名字,这样就在本地创建了一个ifoxcad文件夹,里面就是本项目的所有源码。
-
-```
-git clone https://gitee.com/yourname/ifoxcad.git
-```
-
-当然也可以采用vs的图形化操作,打开vs,选择 克隆存储库-->填入仓库地址和存放路径-->点击克隆。新手小白推荐用此办法。
-
-打开ifoxcad文件夹,双击解决方案文件,打开vs,等待项目打开,加载nuget包,然后生成就可以了。
-
-**切记,不要用低版本的vs打开本项目,因为本项目采用了某些新的语法,所以老版本的vs是不兼容的。**
-
-#### 五、IFoxCad 项目模版
-
-可以在vs扩展菜单-管理扩展中搜索ifoxcad,即可安装项目模板。使用项目模版可以方便的创建支持多目标多版本的使用ifoxcad类库的项目和类。如果无法在vs的市场里下载,就去上面的QQ群里下载。
-
-项目模版里的自动加载选择了简单api,ifox还提供了一套功能更强大的api,具体的可以参考[自动加载和初始化](/docs/autoreg.md)。
-
-#### 六、使用IFoxCad的几种方式
-
-目前ifox提供了三种使用方式,**建议一般的用户使用第二种源码包的形式。有志于本项目发展并想提交点代码的可以选择第三种。**
-
-- 第一种是直接使用普通的nuget包。
-
- 此种方式使用便捷,只要在项目中引用了IFox.CAD.ACAD的包,就可以直接使用了。缺点一是无法控制ifox提供的元组功能的屏蔽,导致和其他的三方包的冲突;二是生成目录里带有ifox的dll。
-
-- 第二种是使用源码包。
-
- 此种方式使用便捷,只要在项目中引用了IFox.Basal.Source和IFox.CAD.Source两个nuget包就可以直接使用了。优点就是使用简单,生成的目录里没有ifox的dll,同时还可以通过定义预处理常量的方式屏蔽ifox提供的元组等功能。缺点就是无法修改源码,即便解包修改了,也不会同步到nuget上。
-
-- 第三种是使用git子模块。
-
- 此种方法使用步骤复杂,需要熟悉git及其子模块的使用,需要引用ifox里的共享项目文件。优点就是可以使用最新的代码,可以修改代码。具体的可以参考如下说明进行:
-
- **让 IFox 作为您的子模块**
-
- IFox的develop分支是一个多cad版本分支,您可以利用此作为您的[git项目子模块](https://www.cnblogs.com/JJBox/p/13876501.html#_label13).
-
- 子模块是以`共享工程`的方式加入到您的工程的,其为`IFox.CAD.Shared`:
-1. 千万不要用`IFox.CAD.ACAD`内的工程作为引用,否则您将遭遇cad加载失效.
-
-2. 一些全局命名空间的缺少,我们也建议您使用全局命名空间来补充,
- 您只需要按照`IFox.CAD.ACAD`的`GlobalUsings.cs`文件一样添加就好了.
-
-3. 若您使用acad是09版本以下的,比如 07 08版本,建议你升级至09 版本以上.
-
-4. 上面的例子告诉了大家如何使用子模块。
-
-#### 七、软件架构及相关说明
-
-1. [软件架构说明](/docs/关于IFoxCAD的架构说明.md)
-
-2. [扩展函数说明](/docs/关于扩展函数的说明.md)
-
-3. [事务管理器用法](/docs/DBTrans.md)
-
-4. [选择集过滤器用法](/docs/SelectionFilter.md)
-
-5. [符号表用法](/docs/SymbolTable.md)
-
-6. [WPF支持](/docs/WPF.md)
-
-7. [自动加载与初始化](/docs/autoreg.md)
-
-8. 天秀的打开模式提权
-
- 由于cad的对象是有打开模式,是否可写等等,为了安全起见,在处理对象时,一般是用读模式打开,然后需要写数据的时候在提权为写模式,然后在降级到读模式,但是这个过程中,很容易漏掉某些步骤,然后cad崩溃。为了处理这些情况,内裤提供了提权类来保证读写模式的有序转换。
-
- ```csharp
- // 第一种方式,采用的是事务管理的模式
- using(line.ForWrite()) // 开启对象写模式提权事务
- {
- // 处理代码
- } // 关闭事务自动处理读写模式
- // 第二种方式,采用的是委托的形式
- line.ForWrite(e => {
- // 处理代码
- });
- ```
-
-9. 未完待续。。。。
diff --git "a/docs/0x01\344\273\243\347\240\201\350\247\204\350\214\203.assets/2HJE@WH1`PPUBOH2ZFL$BT.png" "b/docs/0x01\344\273\243\347\240\201\350\247\204\350\214\203.assets/2HJE@WH1`PPUBOH2ZFL$BT.png"
deleted file mode 100644
index 459930b8d54d075d94b4d06e960fbbc7edbdd17b..0000000000000000000000000000000000000000
Binary files "a/docs/0x01\344\273\243\347\240\201\350\247\204\350\214\203.assets/2HJE@WH1`PPUBOH2ZFL$BT.png" and /dev/null differ
diff --git "a/docs/0x01\344\273\243\347\240\201\350\247\204\350\214\203.md" "b/docs/0x01\344\273\243\347\240\201\350\247\204\350\214\203.md"
deleted file mode 100644
index 26f09091f8e0321b4418e199aaa47792282ff1b5..0000000000000000000000000000000000000000
--- "a/docs/0x01\344\273\243\347\240\201\350\247\204\350\214\203.md"
+++ /dev/null
@@ -1,132 +0,0 @@
-# IFox工程规范
-
-## 代码规范
-
-### 0x01 分离逻辑代码和业务代码
-
-Good:
-
-```c#
-foreach (xx in yyy)
- if (xx == "a")
- {
- 业务();
- break;
- }
-```
-
-Bad:
-
-```c#
-bool flag = false;
-foreach (xx in yyy)
- if (xx == "a")
- {
- 业务();
- flag = true;
- break;
- }
-if(!flag)
- 其他业务();
-```
-
-Good:
-
-```c#
-bool flag = false;
-foreach (xx in yyy)
- if (xx == "a")
- {
- flag = true;
- break;
- }
-if(!flag)
- 其他业务();
-else
- 业务();
-```
-
-主要原因是统一业务在判断分支上,能够更清晰分离逻辑代码和业务代码.
-
-### 0x02 分离逻辑代码和业务代码
-
-
-
-上述代码中出现了这种情形: for {业务1,业务2,业务1,业务2....}
-
-如果有这样的逻辑,那么我们看代码的时候总是认为业务2某种条件必须要跟着业务1.
-
-优化代码的人一看:这代码就不能动了!! 相信我,若干年后的你就是这个优化代码的人.
-
-所以这样的情况下,我们采用的是用个`List`收集拆离(业务)的id,然后在最后进行循环拆离(业务).
-
-### 0x03 .editorconfig 配置要求
-
-c#的代码风格是两个大括号隔行
-
-```c#
-if()
-{
- ...
-}
-```
-
-但是,由于vs没有制作好的原因,导致`委托箭头`代码格式化总是会出现格式化错误.
-所以我们推荐用 .editorconfig 文件约束这个`委托箭头`
-
-在.edirorconfig文件上面增加此句:
-
-```
-csharp_style_var_elsewhere = false
-```
-
-没有这个文件的话,请使用如下步骤:
-
-```mermaid
-graph LR
-vs --> 选项 --> 文本编辑器 --> c# -->代码样式,展开它 --> 格式设置 --> 新行 --> 右页,大括号的新行选项 --> 将lambda表达式的左括号置于新行,取消掉勾勾
-```
-
-保存为 .editorconfig 文件,并放在.sln旁边,加入git管理:
-
-```mermaid
-graph LR
-vs --> 选项 --> 文本编辑器 --> c# -->代码样式 --> 右页,基于设置生成.editorconfig文件 --> 保存到工程中
-```
-
-以后每次打开工程vs会自动识别这个 .editorconfig 文件,而不会用你电脑默认设置的.
-
-### 0x04 所有的注释符号//后面加空格
-
-利用此正则替换:
-
-```
-(?
- {
- ltt.AsciiDescription = "虚线";
- ltt.PatternLength = 0.95; //线型的总长度
- ltt.NumDashes = 4; //组成线型的笔画数目
- ltt.SetDashLengthAt(0, 0.5); //0.5个单位的划线
- ltt.SetDashLengthAt(1, -0.25); //0.25个单位的空格
- ltt.SetDashLengthAt(2, 0); // 一个点
- ltt.SetDashLengthAt(3, -0.25); //0.25个单位的空格
- });
- // 这段代码同时演示了 ifoxcad 类库关于符号表的public ObjectId Add(string name, Action action)这个函数的用法。
- // 或者直接调用:
- tr.LinetypeTable.Add("hah", "虚线",0.95,new double[]{0.5,-0.25,0,-0.25});
- // 获取线型表
- tr.LinetypeTable["hah"];
- ```
-
- **其他符号表的操作类同。如果类库没有提供的Add函数的重载,那么Action委托可以完成你想完成的所有事情。**
-
-## 基础属性操作
-
-事务管理器类提供了`Document`、 `Editor` 、`Database`三个属性来在事务内部处理相关事项。
-
-同时还提供了关于字典的相关属性。
-
-## 对象获取操作
-
-提供了1个泛型 `GetObject`函数的重载来根据ObjectId来获取到对象。
-
-## 字典操作(未完待续)
-
-- 扩展字典
-
- `SetXRecord` 保存扩展数据到字典
-
- `GetXRecord ` 获取扩展数据
-
-- 对象字典
-
- `SetToDictionary` 保存数据到字典
-
- `GetFromDictionary` 从字典获取数据
-
- `GetSubDictionary` 获取子对象字典
diff --git a/docs/SelectionFilter.md b/docs/SelectionFilter.md
deleted file mode 100644
index bc31b55c3c7d630bd238e99c76ba8e830b4210fe..0000000000000000000000000000000000000000
--- a/docs/SelectionFilter.md
+++ /dev/null
@@ -1,208 +0,0 @@
-# 选择集过滤器用法
-
-## 选择集过滤器简介
-
-桌子提供了选择集过滤器是为了更精确的选择对象。可以通过使用选择过滤器来限制哪些对象被选中并添加到选择集,选择过滤器列表通过属性或类型过滤所选对象。
-
-在桌子的 .net api 中:选择过滤器由一对 TypedValue 参数构成。TypedValue 的第一个参数表明过滤器的类型(例如对象),第二个参数为要过滤的值(例如圆)。过滤器类型是一个 DXF 组码,用来指定使用哪种过滤器。
-
-默认的使用桌子api来创建选择集(带过滤器)分三步:
-
-1. 创建一个TypedValue数组来定义过滤器条件
-
- ```csharp
- TypedValue[] acTypValAr = new TypedValue[1]; // 创建数组
- acTypValAr.SetValue(new TypedValue((int)DxfCode.Start, "CIRCLE"), 0);
- // 添加一个过滤条件,例如选择圆
-
- // 如果要创建多个过滤条件怎么办?
- TypedValue[] acTypValAr = new TypedValue[3];
- acTypValAr.SetValue(new TypedValue((int)DxfCode.Color, 5), 0);
- acTypValAr.SetValue(new TypedValue((int)DxfCode.Start, "CIRCLE"), 1);
- acTypValAr.SetValue(new TypedValue((int)DxfCode.LayerName, "0"), 2);
- // 实际上只要不停的往数组里添加条件就可以了
- ```
-
-2. 创建SelectionFilter对象
-
- ```csharp
- // 将过滤器条件赋值给 SelectionFilter 对象
- SelectionFilter acSelFtr = new SelectionFilter(acTypValAr);
- ```
-
-3. 创建选择集
-
- ```csharp
- // 请求用户在图形区域选择对象
- PromptSelectionResult acSSPrompt;
- acSSPrompt = acDocEd.GetSelection(acSelFtr);
- ```
-
-看起来很是简单对不对,单个条件和多个条件的过滤非常简单。当指定多个选择条件时,AutoCAD 假设所选对象必须满足每个条件。我们还可以用另外一种方式定义过滤条件。对于数值项,可以使用关系运算(比如,圆的半径必须大于等于 5.0)。对于所有项,可以使用逻辑运算(比如单行文字或多行文字)。使用 DXF 组码-4 或常量 DxfCode.Operator 表示选择过滤器中的关系预算符类型。运算符本身用字符串表示。
-
-比如:
-
-1. 过滤半径大于等于5.0的圆
-
- ```csharp
- TypedValue[] acTypValAr = {
- new TypedValue((int)DxfCode.Start, "CIRCLE"),
- new TypedValue((int)DxfCode.Operator, ">="),
- new TypedValue(40, 5)
- };
- ```
-
-2. 过滤单行文本或者多行文本
-
- ```csharp
- TypedValue[] acTypValAr = {
- new TypedValue((int)DxfCode.Operator, "")
- };
- ```
-
-3. 更复杂的过滤条件呢?比如选择的对象为不是位于0图层的直线,或者位于2图层的组码10的x坐标>10,y坐标>10的非圆图元。
-
- 对应的lisp代码如下:
-
- ```lisp
- '((-4 . "")
- (-4 . "not>")
- (-4 . "")
- (8 . "2")
- (-4 . ">,>,*")(10 10 10 0)
- (-4 . "and>")
- (-4 . "or>"))
- ```
-
- 对应的c#代码:
-
- ```csharp
- TypedValue[] acTypValAr = {
- new TypedValue((int)DxfCode.Operator, ""),
- new TypedValue((int)DxfCode.Operator, "not>"),
- new TypedValue((int)DxfCode.Operator, ""),
- new TypedValue((int)DxfCode.LayerName, "2"),
- new TypedValue((int)DxfCode.Operator, ">,>,*"),
- new TypedValue(10, new Point3d(10,10,0)),
- new TypedValue((int)DxfCode.Operator, "and>"),
- new TypedValue((int)DxfCode.Operator, "or>")
- };
- ```
-
- 这个过滤器是不是看起来很乱,一眼看去根本不知道是要过滤什么,写起来也很麻烦。所以说,虽然桌子提供了api,但是简单的过滤条件很好用,但是复杂的过滤条件就很复杂了。
-
- 因此IFox内裤提供了关于选择集过滤器的辅助类来帮助用户用更简单的方式来创建选择集的过滤器。
-
-## 内裤过滤器对象与cad过滤器对应关系
-
-IFoxCad内裤对于DxfCode.Operator枚举构建了一些辅助函数来表达关系运算和逻辑运算;提供了dxf函数来表达组码。其对应的关系如下表:
-
-| 内裤过滤器对象、函数 | cad .net api 过滤器对象、函数、枚举 | 备注 |
-|:----------:|:------------------------:|:-------------------:|
-| OpFilter | SelectionFilter | 隐式转换 |
-| OpOr | "" | |
-| Op.Or | "" | |
-| OpAnd | "" | |
-| Op.And | "" | |
-| OpNot | "" | |
-| OpXor | "" | |
-| OpEqual | 相等运算 | |
-| OpComp | 比较运算符 | |
-| Dxf() | 组码函数 | 仅用于过滤器中,不是组码操作函数 |
-| ! | "" | |
-| == | "=" | |
-| != | "!=" | |
-| > | ">" | |
-| < | "<" | |
-| >= | ">=" 或 ">,>,*" | ">,>,*"用于跟point3d比较 |
-| <= | "<=" 或 "<,<,*" | "<,<,*"用于跟point3d比较 |
-| & | "" | |
-| ^ | "" | |
-| \| | "" | |
-
-## 具体用法
-
-IFoxCad内裤提供了三种方式来构建过滤器,其实大同小异,就是写法不一样,用户可以根据自己的喜好来选择。
-
-- 第一种
-
- ```csharp
- var fd =
- new OpOr //定义一个 (-4 . "")
- {
- !new OpAnd //定义(-4 . "")(-4 . "not>")
- {
- { 0, "line" }, //{组码,组码值}
- { 8, "0" }, //{组码,组码值}
- },
- new OpAnd //定义(-4 . "")
- {
- !new OpEqual(0, "circle"), //定义(-4 . "")
- { 8, "2" }, //{组码,组码值}
- { 10, new Point3d(10,10,0), ">,>,*" } //(-4 . ">,>,*")(10 10 10 0)
- },
- };
- editor.SelectAll(fd); //这里直接传入fd就可以了
- ```
-
- 以上代码的含义为:选择的对象为不是位于0图层的直线,或者位于2图层的组码10的x坐标>10,y坐标>10的非圆图元。其同含义的lisp代码如下:
-
- ```lisp
- '((-4 . "")
- (-4 . "not>")
- (-4 . "")
- (8 . "2")
- (-4 . ">,>,*")(10 10 10 0)
- (-4 . "and>")
- (-4 . "or>"))
- ```
-
-- 第二种
-
- ```csharp
- var p = new Point3d(10, 10, 0);
- var f = OpFilter.Bulid(e =>
- !(e.Dxf(0) == "line" & e.Dxf(8) == "0")
- | e.Dxf(0) != "circle"
- & e.Dxf(8) == "2"
- & e.Dxf(10) >= p);
- editor.SelectAll(f); //这里直接传入f就可以了
- ```
-
- 代码含义如第一种。
-
-- 第三种
-
- ```csharp
- var f2 = OpFilter.Bulid(
- e =>e.Or(
- !e.And(e.Dxf(0) == "line", e.Dxf(8) == "0"),
- e.And(e.Dxf(0) != "circle", e.Dxf(8) == "2", e.Dxf(10) >= new Point3d(10, 10, 0)))
- );
- editor.SelectAll(f2); //这里直接传入f2就可以了
- ```
-
- 代码含义如第一种,第三种和第二种的写法非常像,区别就是关于 and 、or 、not 等运算符,一个是采用c#的语法,一个是采用定义的函数。and 与&等价,or与|等价,not 与!等价。
\ No newline at end of file
diff --git a/docs/SymbolTable.md b/docs/SymbolTable.md
deleted file mode 100644
index a5144baea56a722688da09f929cfd04e9d243ed7..0000000000000000000000000000000000000000
--- a/docs/SymbolTable.md
+++ /dev/null
@@ -1,146 +0,0 @@
-# 符号表用法
-
-每个图形文件都包含有9个固定的符号表。不能往数据库里添加新的符号表。如图层表(LayerTable),其中包含图层表记录,还有块表(BlockTable),其中包含块表记录等。所有的图形实体(线、圆、弧等等)都属于一个块表记录。缺省情况下,任何图形文件都包含为模型空间和图纸空间预定义的块表记录。每个符号表都有对应的符号表记录,可以理解为符号表是一个集合,而符号表记录是这个集合的元素。CAD的符号表和符号表记录的对应关系如下:
-
-| 名称 | 符号表 | 符号表记录 |
-|:-------:|:--------------:|:--------------------:|
-| 块表 | BlockTable | BlockTableRecord |
-| 标注样式表 | DimStyleTable | DimStyleTableRecord |
-| 图层表 | LayerTable | LayerTableRecord |
-| 线型表 | LinetypeTable | LinetypeTableRecord |
-| 注册应用程序表 | RegAppTable | RegAppTableRecord |
-| 字体样式表 | TextStyleTable | TextStyleTableRecord |
-| 坐标系表 | UcsTable | UcsTableRecord |
-| 视口表 | ViewportTable | ViewportTableRecord |
-| 视图表 | ViewTable | ViewTableRecord |
-
-那么如何来操作这些符号表呢?下面是一个新建图层的例子:
-
-```csharp
-Document acDoc = Application.DocumentManager.MdiActiveDocument;
-Database acCurDb = acDoc.Database;
-using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
-{
- // 返回当前数据库的图层表
- LayerTable acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId,OpenMode.ForRead) as LayerTable;
- // 检查图层表里是否有图层 MyLayer
- if (acLyrTbl.Has("MyLayer") != true)
- {
- // 以写模式打开图层表
- acLyrTbl.UpgradeOpen();
- // 新创建一个图层表记录,并命名为”MyLayer”
- LayerTableRecord acLyrTblRec = new LayerTableRecord();
- acLyrTblRec.Name = "MyLayer";
- // 添加新的图层表记录到图层表,添加事务
- acLyrTbl.Add(acLyrTblRec);
- acTrans.AddNewlyCreatedDBObject(acLyrTblRec, true);
- //提交修改
- acTrans.Commit();
- }
- // 关闭事务,回收内存;
-}
-```
-
-上面的例子用了20多行的代码来完成一个很简单的功能,这就是AutoCAD提供的api太过于基础,没有进行进一步的封装造成。那么如果我们单独为图层表封装一个函数来处理图层表,其他的8个符号表也要同样的各自封装函数,这样看起来没什么问题,但是对于代码的复用却没有很好的考虑进去。仔细思考一下,其实对于符号来说无非就是增删改三个主要的操作等,对于符号表记录来说无非就是一些属性的操作,增加实体的操作等。那么有没有一种办法可以统一管理9个符号表呢?其实AutoCAD提供了9个符号表和符号表记录的抽象基类,SymbolTable和SymbolTableRecord,但是这两个类提供的功能又很简单,只有寥寥几个函数和属性,完全不能满足我们的需求。因此ifoxcad内裤提供了符号表类来封装9个符号表的大部分功能。那么用内裤来完成上述的操作是什么样子的呢?见下面的例子:
-
-```csharp
-// 以下代码采用最新的c#版本语法
-using var tr = new DBTrans(); // 打开事务
-var layertable = tr.LayerTable.Add("MyLayer"); //添加图层
-```
-
-同样的功能我们只需要两行就可以搞定了。那么有同学会问了,我同样单独对每个符号表的封装一样可以达到这个效果?是的,确实可以达到一样的效果,但是我只封装了一次,只是针对符号表的差异部分做了一些增量的处理,其他的代码都是复用的,而你要写9次。
-
-言归正传,通过上述的例子,我们会发现几个现象:
-
-1. 符号表的操作是在事务内。
-2. 符号表成了事务的属性
-3. 添加符号表记录到符号表调用Add函数就可以了(其实提供了好多的重载,来完成不同的细粒度的操作)。
-
-符号表的操作都在事务内,这样由事务统一管理符号表的变动,减少出错的可能。
-
-符号表作为事务的属性,那么获取符号表记录就变成了属性的索引值。`var layertable = tr.LayerTable["MyLayer"];`
-
-不管是什么符号表,都是一个Add函数搞定添加操作。
-
-而删除就是:`tr.LayerTable.Remove("1");` *注意,这里的关于删除图层的操作需要调用Delete函数*
-
-看,我教会了你操作图层表,那么其他的8个表你都会了,都是一样的操作。
-
-## 块表添加图元
-
-一般的情况下,添加图元的操作都是要在事务里完成。目前大部分的添加图元的自定义函数都是DataBase或Editor对象的扩展函数。但是实际上添加图元的本质是读写图形数据库,具体的手段是对块表里的块表记录的读写。而实际的操作其实都是在事务里完成,所以符合cad操作规则的写法其实应该是事务作为一系列操作的主体来进行。因此ifoxcad内裤的封装思路为:扩展块表记录的函数,在事务管理器类里通过属性调用AddEntity函数来添加图元。
-
-对于这个添加图元的操作,一共分为如下几步:
-
-1. 创建图元对象,可以在事务外创建,也可以在事务内创建。
-2. 打开要添加图元的块表记录,在事务内打开。
-3. 添加图元到块表记录
-
-下面看示例:
-
-- 添加图元到当前空间
-
- ```csharp
- // 以下代码采用最新的c#版本语法
- using var tr = new DBTrans(); //开启事务管理器
- var line1 = new Line(new Point3d(0, 0, 0), new Point3d(1, 1, 0)); //定义一个直线
- tr.CurrentSpace.AddEntity(line1); // 将直线添加到当前绘图空间的块表记录
- ```
-
-- 添加图元到模型/图纸空间
-
- ```csharp
- // 以下代码采用最新的c#版本语法
- using var tr = new DBTrans(); //开启事务管理器
- var line1 = new Line(new Point3d(0, 0, 0), new Point3d(1, 1, 0)); //定义一个直线
- tr.CurrentSpace.AddEntity(line1); // 将直线添加到当前绘图空间的块表记录
- tr.ModelSpace.AddEntity(line1); // 将直线添加到当前模型空间的块表记录
- tr.PaperSpace.AddEntity(line1); // 将直线添加到当前图纸空间的块表记录
- ```
-
-- 添加图元到块表
-
- ```csharp
- // 以下代码采用最新的c#版本语法
- using var tr = new DBTrans(); //开启事务管理器
- var line1 = new Line(new Point3d(0, 0, 0), new Point3d(1, 1, 0)); //定义一个直线
- var btr = tr.BlockTable.Add("test"); //定义一个块表记录
- btr.AddEntity(line1); // 将直线添加到当前控件的块表记录
- ```
-
- 那么大家猜一猜,这个添加到块表是实现了一种什么样的功能。
-
-- 块表
-
- 块表这里需要特殊的说明一下:
-
- 比如说添加一个块,用如下代码:
-
- `tr.BlockTable.Add(blockName, btr => btr.AddEntity(ents));`
-
- 这里的blockName就是块名,ents就是图元列表。这种方式虽然可以更细粒度的控制定义的块。
-
- 插入块参照,比如:
-
- `tr.InsertBlock(point,objectid); // 用于插入块参照,提供了重载函数来满足不同的需求`
-
-- 其他函数的介绍
-
- `tr.BlockTable.GetRecord()` 函数,可以获取到块表的块表记录,同理层表等符号表也有同样的函数。
-
- `tr.BlockTable.GetRecordFrom()` 函数,可以从文件拷贝块表记录,同理层表等符号表也有同样的函数。
-
- `tr.BlockTable.GetBlockFrom()` 函数,从文件拷贝块定义,同理层表等符号表也有同样用途的函数。
-
-- 添加图元函数
-
- 内裤提供了一些便利的添加图元函数,可以不用先定义一个entity对象,然后添加到块表记录。
-
- ```csharp
- using var tr = new DBTrans();
- tr.CurrentSpace.AddLine(new Point3d(0,0,0),new Point3d(1,1,0));
- tr.CurrentSpace.AddCircle(new Point3d(0,0,0),10);
- ```
-
-
diff --git a/docs/WPF.md b/docs/WPF.md
deleted file mode 100644
index 73f4f1116be4ef9cff68117b0f2fd86acf32d382..0000000000000000000000000000000000000000
--- a/docs/WPF.md
+++ /dev/null
@@ -1,353 +0,0 @@
-
-
-# WPF支持
-
-在项目文件里将``替换为``。
-
-在``标签里的`NET45`下面添加:
-```xml
-true
-true
-```
-
-最后的项目文件如下:
-
-```xml
-
-
- net47
-
- true
-
- true
-
-
-
-```
-
-# mvvm模式支持
-
-## 一、简单mvvm的实现
-
-使用WPF的最佳实践就是采用mvvm模式,为了支持在cad插件里使用mvvm,ifoxcad内裤定义了两个简单基类来完成属性通知和命令定义。当然这是一种及其简单的mvvm模式的支持,你还要自己手动来写大部分的代码来实现完整的mvvm模式。
-
-要实现mvvm模式,要新建一个XXXView文件,一个XXXViewModel文件。我们应该采用一种通用的命名约定,即所有的gui显示都有XXXView来完成,而所有的业务逻辑都由XXXViewModel来完成。下面以一个具体的示例来说明怎么在cad的插件里使用mvvm模式。
-
-1. 将我们上一节建立的MyWindow1文件改名为MyWindowView,然后将涉及到的类名也全部更改为MyWindowView。
-
-2. 然后将MyWindowView.xaml文件的内容改为:
-
-```xaml
-
-
-
-
-
-
-
-
-```
-
-就是添加了一个文本框,一个按钮。
-
-3. 新建MyWindowViewModel.cs文件,内容如下:
-
-```c#
-using IFoxCad.WPF; // 这里引入IFoxCad.WPF命名空间,以便可以使用ViewModelBase和RelayCommand
-
-namespace Test
-{
- class MyWindowViewModel : ViewModelBase
- {
- // 定义一个属性用于在文本框里显示
- private string _name;
- public string Name
- {
- get { return _name; }
- set
- {
- Set(ref _name, value);
- }
- }
-
- // 定义一个命令用于按钮的点击动作
- private RelayCommand clickCommand;
- public RelayCommand ClickCommand
- {
- get
- {
- if (clickCommand == null)
- {
- clickCommand = new RelayCommand(
- execute => Name = "hello " + Name, // 定义要执行的行为
- can => {return !string.IsNullOrEmpty(Name);}); // 定义命令是否可用
- }
- return clickCommand;
- }
- }
- // 初始化Name属性为 World
- public MyWindowViewModel()
- {
- Name = "World";
- }
- }
-}
-
-```
-
-这里需要注意的是,定义的属性是为了将属性绑定到文本框的Text属性上,这个叫做数据绑定。然后wpf里对于我们winform里的事件其实采用的更高级一些的命令来完成。本示例,定义的命令也是一个属性,这个属性返回一个RelayCommand对象的实例,这是实例的初始化函数包括两个部分,一个是要执行的动作,第二个是确定什么条件下按钮是不可用的,这个是通过命令是否可用来完成,是要命令是不能执行的,wpf会自动将控件切换为不可用状态,使其不可点击。
-
-4. 现在回过头来对在xaml里将刚刚的viewmodel里定义的属性和命令绑定到控件上。
-
-```xaml
-
-
-```
-
-将这两行代码替换一下。然后在后台代码里(MyWindowView.xaml.cs)添加一行代码将viewmodel绑定到view上。
-
-```c#
-public MyWindowView()
-{
- InitializeComponent();
- DataContext = new MyWindowViewModel(); //这里将一个viewmodel的实例绑定到view的DataContext属性上。
-}
-```
-
-5. 至此,一个简单的wpf的mvvm模式的代码就完成了,下面的代码演示了怎么在cad里显示这个wpf窗体。
-
-```c#
-[CommandMethod("test")]
-public void Test()
-{
- var test = new MyWindowView();
- Application.ShowModalWindow(test);
-}
-```
-
-6. 最后,这个窗体的效果是,当你点击按钮时,文本框的文字前面会加上hello。当你将文本框的文字全部删除后,按钮会变成不可用状态。如果你在试验的时候没有这个效果,这是cad的延迟导致的。多删除几次试几次后就会如期运行。
-
-## 二、mvvm中的事件处理
-
-在WPF里,并不是所有的控件都提供了commad属性用于绑定命令,所以还是需要进行控件的事件处理的,比如窗口的Loaded事件,鼠标事件,键盘事件等。关于WPF的事件处理,IFoxCad内裤提供了两种方式进行处理,一种就是利用 **Microsoft.Xaml.Behaviors.dll** 这个类库,利用了 **i:Interaction.Triggers** 标签在xaml文件里将命令绑定到事件上,这种方式是网上比较常见的一种方式;第二种是自定义了一个xaml标签 **eb:EventBinding** ,利用这个标签将命令绑定到事件上。两种方式实现的效果是一样的,但是 **eb:EventBinding** 标签绑定的方式的代码量要小一些。
-
-下面就两种方式实现同一种事件处理的效果提供了两种方式的代码示例作为说明。由于两种方式的差异主要在xaml文件里,ViewModel的代码是一样的。因此主要讲述两种xaml的差异部分,ViewModel的代码直接贴在下面不做讲解。
-
-```c#
-public class TestViewModel : ViewModelBase
-{
-
- private bool _IsReceiveMouseMove = true;
- public bool IsReceiveMouseMove
- {
- get { return _IsReceiveMouseMove; }
- set
- {
- Set(ref _IsReceiveMouseMove, value);
- }
- }
-
- private string _tipText;
- public string TipText
- {
- get { return _tipText; }
- set
- {
- Set(ref _tipText, value);
- }
- }
-
-
-
- private RelayCommand loadedCommand;
-
- public RelayCommand LoadedCommand
- {
- get
- {
- if (loadedCommand == null)
- {
- loadedCommand = new RelayCommand(execute => MessageBox.Show("程序加载完毕!"));
-
- }
- return loadedCommand;
- }
-
- }
-
- private RelayCommand mouseMoveCommand;
- public RelayCommand MouseMoveCommand
- {
- get
- {
- if (mouseMoveCommand == null)
- {
- mouseMoveCommand =
- new RelayCommand(
- e =>
- {
- var point = e.GetPosition(e.Device.Target);
- var left = "左键放开";
- var mid = "中键放开";
- var right = "右键放开";
-
- if (e.LeftButton == MouseButtonState.Pressed)
- {
- left = "左键放下";
- }
- if (e.MiddleButton == MouseButtonState.Pressed)
- {
- mid = "中键放下";
- }
- if (e.RightButton == MouseButtonState.Pressed)
- {
- right = "右键放下";
- }
-
- TipText = $"当前鼠标位置 X:{point.X} Y:{point.Y} 当前鼠标状态:{left} {mid} {right}.";
- },
- o => IsReceiveMouseMove);
- }
- return mouseMoveCommand;
- }
- }
-}
-```
-
-### 2.1 自定义标签的方式
-
-首先是在xaml里引入命名空间。
-
-`xmlns:eb="clr-namespace:IFoxCAD.WPF;assembly=IFoxCAD.WPF"`
-
-然后
-
-`Loaded="{eb:EventBinding Command=LoadedCommand}"`
-
-`MouseMove="{eb:EventBinding Command=MouseMoveCommand,CommandParameter=$e}"` 这里要注意的是显式的传入了鼠标移动事件的参数。
-
-注意命令参数部分,如果这个事件是带参数的,或者说这个命令是带参数的,要传入参数。
-
-关于命令及命令参数使用方式如下:
-
-- Command
- 1. `{eb:EventBinding}` 利用简单的名字匹配来自动搜寻命令,也就是说不用指定命令名,不是很推荐。
- 2. `{eb:EventBinding Command=CommandName}` 指定命令名,建议总是使用这种方式
-
-- CommandParameter
- 1. `$e` (事件参数,这里特指的是事件本身带的参数,也就是你以前写事件的处理函数时候的XXXXEventArgs e这个参数)
- 2. `$this` or `$this.Property` (view本身或者属性)
- 3. `string` (要传入的字符串)
-
-完整的xaml代码如下:
-
-```xaml
-
-
-
-
-
-
-```
-
-### 2.2 利用Behaviors的方式
-
-首先nuget安装**Microsoft.Xaml.Behaviors.Wpf**包。
-
-然后在xaml文件里,引入命名空间。
-
-`xmlns:eb="clr-namespace:IFoxCad.WPF;assembly=IFoxCad"`
-
-`xmlns:i="http://schemas.microsoft.com/xaml/behaviors"`
-
-然后绑定命令到事件上:
-
-```xaml
-
-
-
-
-
-
-
-
-```
-
-细心的同学可能会发现绑定命令的地方标签是不一样的。
-
-**i:InvokeCommandAction** 这个标签是由 **Microsoft.Xaml.Behaviors.Wpf** 包提供的。
-
-**eb:EventCommand** 这个标签是由IFoxCad内裤提供的。
-
-两者的区别就是InvokeCommandAction 是不能传入事件的参数的,所以为了处理事件参数自定义了EventCommand。就如同上面的鼠标移动事件,是有时间参数要处理的,所以用了自定义的EventCommand,虽然xaml文件里没有显式的传入这个参数。
-
-虽然InvokeCommandAction这个标签的后面是可以带命令参数的,比如:
-
-```xaml
-
-
-
-
-
-```
-
-但是这个命令参数是不能处理事件自带的参数的 。
-
-最后是完整的xaml代码:
-
-```xaml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-### 2.3 关于两种方式的选择
-
-送给选择困难症的:如果可以选择自定义标签的方式,简单一些。遇到问题解决不了,就用behaviors的方式,网上的资源丰富一些,也许能找到你的答案。
-
-## 三、 关于mvvm模式的建议
-
-我们并不推荐严格的mvvm模式,主要原因是要引入比如message模式等方式处理类似窗口关闭,窗口间通信等问题。鉴于cad插件的界面复杂程度还没到后台事件满天飞,逻辑复杂的地步,因此后台写点事件处理,界面和后逻辑混在一起也未尝不可。
-
-仅仅是建议,你爱怎样就怎样。
-
diff --git a/docs/autoreg.md b/docs/autoreg.md
deleted file mode 100644
index 72f377c24b7129336ebfa5a8e22f55fbc57697c5..0000000000000000000000000000000000000000
--- a/docs/autoreg.md
+++ /dev/null
@@ -1,62 +0,0 @@
-## 自动加载与初始化
-
-### 1、简单版
-
-为了将程序集的初始化和通过写注册表的方式实现自动加载统一设置,减少每次重复的工作量,类裤提供了`AutoLoad`抽象类来完成此功能,只要在需要初始化的类继承`AutoLoad`类,然后实现`Initialize()` 和 `Terminate()` 两个函数就可以了。
-特别强调的是,一个程序集里只能有一个类继承,不管是不是同一个命名空间。
-
-如果要将dll的目录加入支持文件目录,请在 `Initialize` 函数中调用`AppendSupportPath(CurrentDirectory.FullName);`
-
-其他需要初始化执行的函数及设置都需要在 `Initialize` 函数中执行。
-
-### 2、功能版
-
-使用特性进行分段初始化是目前最佳选择,下面的说明已和最新版本不符,等待修正吧。
-
-```csharp
- using Autodesk.AutoCAD.Runtime;
- using IFoxCAD.Cad;
- using System;
- using System.Reflection;
-
-/*
- * 自动执行接口
- * 这里必须要实现一次这个接口,才能使用 IFoxInitialize 特性进行自动执行
- */
-public class CmdINI : AutoRegAssem
-{
- // 这里可以写任何普通的函数,也可以写下面 AutoTest 类里的实现了 IFoxInitialize 特性的初始化函数
- // 继承AutoRegAssem的主要作用是写注册表用来自动加载dll,同时执行实现了 IFoxInitialize 特性的函数
- // 注意这里的自动执行是在cad启动后,加载了dll之后执行,而不是运行命令后执行。
-
- [IFoxInitialize]
- public void InitOne()
- {
- // TODO 您想在加载dll之后自动执行的函数
- // 可以随便在哪里类里 可以多次实现 IFoxInitialize 特性
- }
-
-}
-
-// 其他的类中的函数:
-// 实现自动接口之后,在任意一个函数上面使用此特性,减少每次改动 CmdINI 类
-public class AutoTest
-{
- [IFoxInitialize]
- public void Initialize()
- {
- // TODO 您想在加载dll之后自动执行的函数
- }
- [IFoxInitialize]
- public void InitTwo()
- {
- // TODO 您想在加载dll之后自动执行的函数
- // 可以随便在哪里类里 可以多次实现 IFoxInitialize 特性
- }
- [IFoxInitialize(isInitialize: false)] // 特性的参数为false的时候就表示卸载时执行的函数
- public void Terminate()
- {
- // TODO 您想在关闭cad时自动执行的函数
- }
-}
-```
diff --git "a/docs/png/ifoxcad\347\224\250\346\210\267\344\272\244\346\265\201\347\276\244\347\276\244\344\272\214\347\273\264\347\240\201.png" "b/docs/png/ifoxcad\347\224\250\346\210\267\344\272\244\346\265\201\347\276\244\347\276\244\344\272\214\347\273\264\347\240\201.png"
deleted file mode 100644
index a9d08c483b80f21d4b0ac6a0afe80f9b6b4233e6..0000000000000000000000000000000000000000
Binary files "a/docs/png/ifoxcad\347\224\250\346\210\267\344\272\244\346\265\201\347\276\244\347\276\244\344\272\214\347\273\264\347\240\201.png" and /dev/null differ
diff --git a/docs/png/nuget.png b/docs/png/nuget.png
deleted file mode 100644
index d0af980fedd9eca39d0e0bf787111685242994ac..0000000000000000000000000000000000000000
Binary files a/docs/png/nuget.png and /dev/null differ
diff --git a/docs/png/nuget1.png b/docs/png/nuget1.png
deleted file mode 100644
index 91983ffef3b246ea796296b14fe09963663de184..0000000000000000000000000000000000000000
Binary files a/docs/png/nuget1.png and /dev/null differ
diff --git a/docs/png/standard.png b/docs/png/standard.png
deleted file mode 100644
index dfc34fecb32120f54436115208a4abaea2dac516..0000000000000000000000000000000000000000
Binary files a/docs/png/standard.png and /dev/null differ
diff --git "a/docs/\345\205\263\344\272\216IFoxCAD\347\232\204\346\236\266\346\236\204\350\257\264\346\230\216.md" "b/docs/\345\205\263\344\272\216IFoxCAD\347\232\204\346\236\266\346\236\204\350\257\264\346\230\216.md"
index f96d39d487c1f6c2af8a2f3257fa3cc3bbfd619d..ee3a985ec0fb36b41e94505d3f8f96379e1c029b 100644
--- "a/docs/\345\205\263\344\272\216IFoxCAD\347\232\204\346\236\266\346\236\204\350\257\264\346\230\216.md"
+++ "b/docs/\345\205\263\344\272\216IFoxCAD\347\232\204\346\236\266\346\236\204\350\257\264\346\230\216.md"
@@ -71,42 +71,30 @@ IFoxCAD是基于NFOX类库的重制版,主要是提供一个最小化的内核
## 一、组织结构图
- IFoxCAD
-
- - IFoxCAD.Basal - cad以外常用的类库
-
- - LinqEx - linq扩展类
-
- - LoopList - 环链表
-
- - IFoxCAD.Cad - cad相关的类库
-
- - Runtime - 包含系统级别的功能
-
- - AcadVersion - cad版本号类
- - AssemInfo - 程序集信息
- - AutoRegAssem - 程序集加载类型
- - DBTrans - 事务处理类
- - Env - 系统管理类
- - SymbolTable - 符号表类
-
- - ExtensionMethod - 扩展函数,以Ex结尾
-
- - SymbolTableEx - 符号表扩展类
- - SymbolTableRecordEx - 符号表记录扩展类
- - EntityEx - 实体扩展类
- - 。。。。。。
-
- - ResultData
-
- - 待补充。。。
-
- - SelectionFilter
+```
+├───bin -- 用于放置生成的nuget包和dll
+├───docs -- 架构及api定义说明文档
+├───src -- 源码目录
+│ ├───CADShared -- 共享项目,所有的代码都在这里
+│ │ ├───Algorithms -- 基础算法和数据结构
+│ │ ├───Assoc -- 关联函数
+│ │ ├───Basal -- 一些基础类的函数
+│ │ ├───ExtensionMethod -- 扩展函数
+│ │ ├───Initialize -- 初始化
+│ │ ├───PE -- PE
+│ │ ├───ResultData -- 扩展数据
+│ │ ├───Runtime -- 核心类
+│ │ └───SelectionFilter -- 选择集过滤器类
+│ ├───IFoxCAD.AutoCad -- AutoCAD的类库,内部除了globalusing外无其他代码
+│ └───IFoxCAD.ZwCad -- AutoCAD的类库,内部除了globalusing外无其他代码
+└───tests -- 测试类
+ ├───TestAcad2025 -- autocad测试
+ ├───TestShared -- 共享项目,所有的测试代码都在这里
+ └───TestZcad2025 -- zwcad测试
- - 待补充。。。
-
- - IFoxCAD.WPF - wpf的mvvm模式相关的类库
-
- ## 二、关于DBTrans类的说明
+ ```
+
+## 二、关于DBTrans类的说明
### 2.1 为什么要构建DBTrans类?
@@ -128,17 +116,18 @@ DBTrans的每个实例都具有这些属性,而这些属性就对应于cad的
属性:
-- Top ---返回当前事务
+- Top ---返回当前DBTrans对象
- Database ---数据库
- Document ---文档
- Editor ---命令行
-- Trans ---事务管理器
+- Transaction ---事务
构造函数:
-- DBTrans(Document doc = null, bool commit = true)
+- DBTrans(Document? doc = null, bool commit = true, bool docLock = false)
- DBTrans(Database database, bool commit = true)
-- DBTrans(string fileName, bool commit = true)
+- DBTrans(string fileName, bool commit = true, FileOpenMode fileOpenMode = FileOpenMode.OpenForReadAndWriteNoShare,
+ string? password = null, bool activeOpen = false)
符号表:
@@ -152,10 +141,27 @@ DBTrans的每个实例都具有这些属性,而这些属性就对应于cad的
- ViewTable 视图表
- ViewportTable 视口表
+字典:
+
+- NamedObjectsDict 命名对象字典
+- GroupDict 组字典
+- MLeaderStyleDict 多重引线样式字典
+- MLStyleDict 多线样式字典
+- MaterialDict 材质字典
+- TableStyleDict 表格样式字典
+- VisualStyleDict 视觉样式字典
+- ColorDict 颜色字典
+- PlotSettingsDict 打印设置字典
+- PlotStyleNameDict 打印样式表名字典
+- LayoutDict 布局字典
+- DataLinkDict 数据链接字典
+- DetailViewStyleDict 详细视图样式字典
+- SectionViewStyleDict 剖面视图样式字典
+
方法:
- GetObject ---根据对象id获取图元对象
-- 。。。
+- Task 前台后台任务分别处理
接口:
diff --git "a/docs/\345\205\263\344\272\216\346\211\251\345\261\225\345\207\275\346\225\260\347\232\204\350\257\264\346\230\216.md" "b/docs/\345\205\263\344\272\216\346\211\251\345\261\225\345\207\275\346\225\260\347\232\204\350\257\264\346\230\216.md"
deleted file mode 100644
index 41d9336e6e47afa45e72ad28de9cc455d510d320..0000000000000000000000000000000000000000
--- "a/docs/\345\205\263\344\272\216\346\211\251\345\261\225\345\207\275\346\225\260\347\232\204\350\257\264\346\230\216.md"
+++ /dev/null
@@ -1,15 +0,0 @@
-# 关于扩展函数的说明
-
-## 一、命名规则
-
-扩展函数全部都放在 **ExtensionMethod** 文件夹里。
-
-然后每个类别都需要分别建立一个以EX为结尾的文件。比如:
-
-DBObjectEx 实体对象扩展类
-
-SymbolTableRecordEx 实体对象扩展类
-
-EditorEx.cs 表示关于命令的扩展
-
-
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..1e9570c669295da03aa67b9dc0d74958db582b66
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,49 @@
+# IFoxCAD 说明
+
+基于.NET的Cad二次开发类库。
+
+#### 一、项目来源
+
+起初 **雪山飞狐(又狐哥)** 在明经论坛发布了[开源库](http://bbs.mjtd.com/thread-75701-1-1.html),后来狐哥自己的项目进行了极大的丰富后形成NFox类库。然后 **落魄山人** 在征得 雪山飞狐的同意后,对NFox类库进行了整理,增加了注释等,重新发布了NFox类库。
+
+后来,经过一段时间的更新后,由于莫名其妙的原因NFox类库挂掉了。而这时山人同学已经基本吃透NFox类库,考虑到NFox的封装过于复杂,遂进行了重构。
+
+重构的类库命名为IFoxCAD, 寓意为:**I(爱)Fox(狐哥)**,本项目发布于**Inspire Function(中文名:跃动方程)** 组织下,感谢 **小轩轩** 给起的名字。
+
+可以加群交流:
+
+[点击链接加入群聊【IFoxCad交流群】](https://qm.qq.com/q/tJZELgdzHi)
+
+ **QQ群为丐群,所以也可以加入qq频道交流:**
+
+[点击链接加入QQ频道【CAD二次开发】](https://pd.qq.com/s/2wmmkv4c2)
+
+#### 二、 使用帮助
+
+IFoxCAD的项目文档请看 **[IFoxCAD类库从入门到精通](https://www.kdocs.cn/l/cc6ZXSa0vMgD)**。
+
+IFoxCAD的API文档请看 **[IFoxCAD API 文档](https://inspirefunction.github.io/ifoxdoc/)**。**请注意这个网站需要科学浏览**
+
+
+#### 三、IFoxCad 项目模版
+
+目前由于IFoxCad的版本分为0.5、0.6、0.7三个大的版本同时在发布,所以项目模版分为两个主要的版本:
+
+- vs模版插件
+- net项目模版
+
+建议使用net项目模版来创建项目,具体的区别可以去上面的文档里查看 **[4.4 IFoxCad 项目模版](https://kdocs.cn/l/cc6ZXSa0vMgD?linkname=ulYcRm6f9a)**
+
+#### 四、使用IFoxCad的几种方式
+
+目前IFoxCad的几种使用方式:
+**[4.5 使用IFoxCad的几种方式](https://kdocs.cn/l/cc6ZXSa0vMgD?linkname=mhBJO1Vchu)**
+
+#### 五、参与项目的方式
+
+期待你的参与,你可以做如下的工作来帮助IFoxCad发展:
+
+- 如果你在使用的过程中发现IFoxCad的某些不足或者bug,你可以在 [项目issues](https://gitee.com/inspirefunction/ifoxcad/issues) 里提交issue来供开发人员进行完善。
+- 帮助开发人员编写使用文档,文档地址见 **[IFoxCAD类库从入门到精通](https://www.kdocs.cn/l/cc6ZXSa0vMgD)**
+- fork本项目,修复bug,增加功能,并提交pr。
+
diff --git a/src/Basal/Directory.Build.props b/src/Basal/Directory.Build.props
deleted file mode 100644
index 77a2d3711db05b158825e750d59ed1f4f864e9a9..0000000000000000000000000000000000000000
--- a/src/Basal/Directory.Build.props
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
- 0.5.2.4
- 完善源码包,源码包映射原始目录
-
-
-
- preview
- enable
- true
- ..\..\..\bin\$(Configuration)\
- true
- true
- True
- True
-
-
-
-
-
- InspireFunction
- xsfhlzh;vicwjb;liuqihong
- InspireFunction
- 基于.NET的二次开发基本类库.
- MIT
- true
- https://gitee.com/inspirefunction/ifoxcad
- https://gitee.com/inspirefunction/ifoxcad.git
- git
- IFox;C#;NET;Common;Basal
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Basal/IFox.Basal.Shared/CLS/Index.cs b/src/Basal/IFox.Basal.Shared/CLS/Index.cs
deleted file mode 100644
index b84f4dffd68334952188669e6fa487d76dcb89d0..0000000000000000000000000000000000000000
--- a/src/Basal/IFox.Basal.Shared/CLS/Index.cs
+++ /dev/null
@@ -1,151 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-#if !NOINDEX
-namespace System;
-
-
-#if NET45
-using System.Runtime.CompilerServices;
-#endif
-/// Represent a type can be used to index a collection either from the start or the end.
-///
-/// Index is used by the C# compiler to support the new index syntax
-///
-/// int[] someArray = new int[5] { 1, 2, 3, 4, 5 } ;
-/// int lastElement = someArray[^1]; // lastElement = 5
-///
-///
-public readonly struct Index : IEquatable
-{
- private readonly int _value;
-
- /// Construct an Index using a value and indicating if the index is from the start or from the end.
- /// The index value. it has to be zero or positive number.
- /// Indicating if the index is from the start or from the end.
- ///
- /// If the Index constructed from the end, index value 1 means pointing at the last element and index value 0 means pointing at beyond last element.
- ///
-#if NET45
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
-#endif
- public Index(int value, bool fromEnd = false)
- {
- if (value < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
- }
-
- if (fromEnd)
- _value = ~value;
- else
- _value = value;
- }
-
- // The following private constructors mainly created for perf reason to avoid the checks
- private Index(int value)
- {
- _value = value;
- }
-
- /// Create an Index pointing at first element.
- public static Index Start => new(0);
-
- /// Create an Index pointing at beyond last element.
- public static Index End => new(~0);
-
- /// Create an Index from the start at the position indicated by the value.
- /// The index value from the start.
-#if NET45
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
-#endif
- public static Index FromStart(int value)
- {
- if (value < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
- }
-
- return new Index(value);
- }
-
- /// Create an Index from the end at the position indicated by the value.
- /// The index value from the end.
-#if NET45
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
-#endif
- public static Index FromEnd(int value)
- {
- if (value < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
- }
-
- return new Index(~value);
- }
-
- /// Returns the index value.
- public int Value
- {
- get
- {
- if (_value < 0)
- return ~_value;
- else
- return _value;
- }
- }
-
- /// Indicates whether the index is from the start or the end.
- public bool IsFromEnd => _value < 0;
-
- /// Calculate the offset from the start using the giving collection length.
- /// The length of the collection that the Index will be used with. length has to be a positive value
- ///
- /// For performance reason, we don't validate the input length parameter and the returned offset value against negative values.
- /// we don't validate either the returned offset is greater than the input length.
- /// It is expected Index will be used with collections which always have non negative length/count. If the returned offset is negative and
- /// then used to index a collection will get out of range exception which will be same affect as the validation.
- ///
-#if NET45
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
-#endif
- public int GetOffset(int length)
- {
- int offset = _value;
- if (IsFromEnd)
- {
- // offset = length - (~value)
- // offset = length + (~(~value) + 1)
- // offset = length + value + 1
-
- offset += length + 1;
- }
- return offset;
- }
-
- /// Indicates whether the current Index object is equal to another object of the same type.
- /// An object to compare with this object
- public override bool Equals(object? value) => value is Index index && _value == index._value;
-
- /// Indicates whether the current Index object is equal to another Index object.
- /// An object to compare with this object
- public bool Equals(Index other) => _value == other._value;
-
- /// Returns the hash code for this instance.
- public override int GetHashCode() => _value;
-
- /// Converts integer number to an Index.
- public static implicit operator Index(int value) => FromStart(value);
-
- /// Converts the value of the current Index object to its equivalent string representation.
- public override string ToString()
- {
- if (IsFromEnd)
- return "^" + ((uint)Value).ToString();
-
- return ((uint)Value).ToString();
- }
-}
-
-#endif
\ No newline at end of file
diff --git a/src/Basal/IFox.Basal.Shared/CLS/Range.cs b/src/Basal/IFox.Basal.Shared/CLS/Range.cs
deleted file mode 100644
index 0318216b8a9dc01a2712633037053f66bdf83c07..0000000000000000000000000000000000000000
--- a/src/Basal/IFox.Basal.Shared/CLS/Range.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-#if !NORANGE
-namespace System;
-
-
-
-#if NET45
-using System.Runtime.CompilerServices;
-#endif
-
-/// Represent a range has start and end indexes.
-///
-/// Range is used by the C# compiler to support the range syntax.
-///
-/// int[] someArray = new int[5] { 1, 2, 3, 4, 5 };
-/// int[] subArray1 = someArray[0..2]; // { 1, 2 }
-/// int[] subArray2 = someArray[1..^0]; // { 2, 3, 4, 5 }
-///
-///
-public readonly struct Range : IEquatable
-{
- /// Represent the inclusive start index of the Range.
- public Index Start { get; }
-
- /// Represent the exclusive end index of the Range.
- public Index End { get; }
-
- /// Construct a Range object using the start and end indexes.
- /// Represent the inclusive start index of the range.
- /// Represent the exclusive end index of the range.
- public Range(Index start, Index end)
- {
- Start = start;
- End = end;
- }
-
- /// Indicates whether the current Range object is equal to another object of the same type.
- /// An object to compare with this object
- public override bool Equals(object? value) =>
- value is Range r &&
- r.Start.Equals(Start) &&
- r.End.Equals(End);
-
- /// Indicates whether the current Range object is equal to another Range object.
- /// An object to compare with this object
- public bool Equals(Range other) => other.Start.Equals(Start) && other.End.Equals(End);
-
- /// Returns the hash code for this instance.
- public override int GetHashCode()
- {
- return Start.GetHashCode() * 31 + End.GetHashCode();
- }
-
- /// Converts the value of the current Range object to its equivalent string representation.
- public override string ToString()
- {
- return Start + ".." + End;
- }
-
- /// Create a Range object starting from start index to the end of the collection.
- public static Range StartAt(Index start) => new(start, Index.End);
-
- /// Create a Range object starting from first element in the collection to the end Index.
- public static Range EndAt(Index end) => new(Index.Start, end);
-
- /// Create a Range object starting from first element to the end.
- public static Range All => new(Index.Start, Index.End);
-
- /// Calculate the start offset and length of range object using a collection length.
- /// The length of the collection that the range will be used with. length has to be a positive value.
- ///
- /// For performance reason, we don't validate the input length parameter against negative values.
- /// It is expected Range will be used with collections which always have non negative length/count.
- /// We validate the range is inside the length scope though.
- ///
-#if NET45
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
-#endif
- // [CLSCompliant(false)]
- public (int Offset, int Length) GetOffsetAndLength(int length)
- {
- int start;
- Index startIndex = Start;
- if (startIndex.IsFromEnd)
- start = length - startIndex.Value;
- else
- start = startIndex.Value;
-
- int end;
- Index endIndex = End;
- if (endIndex.IsFromEnd)
- end = length - endIndex.Value;
- else
- end = endIndex.Value;
-
- if ((uint)end > (uint)length || (uint)start > (uint)end)
- {
- throw new ArgumentOutOfRangeException(nameof(length));
- }
-
- return (start, end - start);
- }
-}
-
-#endif
\ No newline at end of file
diff --git a/src/Basal/IFox.Basal.Shared/CLS/RuntimeHelpers.cs b/src/Basal/IFox.Basal.Shared/CLS/RuntimeHelpers.cs
deleted file mode 100644
index 841c0d59100a271c323809fdee0fedd34f618f1e..0000000000000000000000000000000000000000
--- a/src/Basal/IFox.Basal.Shared/CLS/RuntimeHelpers.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using IFoxCAD.Basal;
-
-namespace System.Runtime.CompilerServices;
-
-/*
- * 1.编译提示多个程序集中定义,屏蔽不了,但是不影响编译
- * 2.发现可以通过定义一个条件编译常量来进行屏蔽。
- * 3.普通包会提示编译器缺少GetSubArray函数,但是源码包不会。所以解决方案就是使用普通包的时候安装TA.System.Runtime.CompilerServices.RuntimeHelpers.GetSubArray nuget包来解决,此包为一个符号包,不会生成多余的dll
- */
-
-
-#if !NORuntimeHelpers
-///
-///
-///
-internal static class RuntimeHelpers
-
-{
- ///
- /// Slices the specified array using the specified range.
- ///
- public static T[] GetSubArray(T[] array, Range range)
- {
- //if (array == null)
- // throw new ArgumentNullException(nameof(array));
- array.NotNull(nameof(array));
-
- (int offset, int length) = range.GetOffsetAndLength(array.Length);
-
- if (default(T)! != null || typeof(T[]) == array.GetType()) // NULLABLE: default(T) == null warning (https://github.com/dotnet/roslyn/issues/34757)
- {
- // We know the type of the array to be exactly T[].
- if (length == 0)
- {
- // return Array.Empty();
- return new T[0];
- }
-
- var dest = new T[length];
- Array.Copy(array, offset, dest, 0, length);
- return dest;
- }
- else
- {
- // The array is actually a U[] where U:T.
- T[] dest = (T[])Array.CreateInstance(array.GetType().GetElementType()!, length);
- Array.Copy(array, offset, dest, 0, length);
- return dest;
- }
- }
-}
-#endif
diff --git a/src/Basal/IFox.Basal.Shared/CLS/TupleElementNamesAttribute.cs b/src/Basal/IFox.Basal.Shared/CLS/TupleElementNamesAttribute.cs
deleted file mode 100644
index 93e61930c31b8277948fa060629cb1d813a04ba1..0000000000000000000000000000000000000000
--- a/src/Basal/IFox.Basal.Shared/CLS/TupleElementNamesAttribute.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Runtime.CompilerServices;
-
-///
-/// Indicates that the use of on a member is meant to be treated as a tuple with element names.
-///
-[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Event)]
-public sealed class TupleElementNamesAttribute : Attribute
-{
- private readonly string[] _transformNames;
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// Specifies, in a pre-order depth-first traversal of a type's
- /// construction, which occurrences are
- /// meant to carry element names.
- ///
- ///
- /// This constructor is meant to be used on types that contain an
- /// instantiation of that contains
- /// element names. For instance, if C is a generic type with
- /// two type parameters, then a use of the constructed type C{, might be intended to
- /// treat the first type argument as a tuple with element names and the
- /// second as a tuple without element names. In which case, the
- /// appropriate attribute specification should use a
- /// transformNames value of { "name1", "name2", null, null,
- /// null }.
- ///
- public TupleElementNamesAttribute(string[] transformNames)
- {
- _transformNames = transformNames ?? throw new ArgumentNullException(nameof(transformNames));
- }
-
- ///
- /// Specifies, in a pre-order depth-first traversal of a type's
- /// construction, which elements are
- /// meant to carry element names.
- ///
- public IList TransformNames => _transformNames;
-}
\ No newline at end of file
diff --git a/src/Basal/IFox.Basal.Shared/CLS/ValueTuple.cs b/src/Basal/IFox.Basal.Shared/CLS/ValueTuple.cs
deleted file mode 100644
index c20902433c6b2e27faccc0f8cf436837c42e460b..0000000000000000000000000000000000000000
--- a/src/Basal/IFox.Basal.Shared/CLS/ValueTuple.cs
+++ /dev/null
@@ -1,2152 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-// #pragma warning disable SA1141 // explicitly not using tuple syntax in tuple implementation
-#if !NOVALUETUPLE
-
-using System.Diagnostics;
-using System.Numerics.Hashing;
-/*
- * 惊惊:
- * 首先是因为有人想要编译的时候只形成一个dll,然后把元组塞入IFox,同时也补充了NET35没有元组的遗憾.
- *
- * 而利用nuget元组包必然会形成依赖地狱.
- *
- * 如果你的工程使用了nuget元组包,就造成了必须要剔除IFox.
- *
- * 改IFox的元组命名空间倒是可以分离两者,但是 vs编译器 无法识别带其他命名空间的元组.
- * 所以元组本身就是冲突的,需要把其他元组卸载掉,由IFox提供.
- */
-
-/*
- * 1. 元组是net47之后提供的特性,所以net47之前的版本是都没有的
- * 2. 通过定义常量的办法将元组屏蔽,很奇怪的是源码包可以,但是普通包不行,所以推荐使用源码包 index和range的情况类似
- * 这种问题就没有很好的解决方式,因为用了ifox就不能用其他的index,range,valuetuple类库,但是其他的三方库却依赖
- * 这些类库,所以还是使用源码包吧。
-*/
-
-#if NET35
-namespace System.Collections
-{
- public interface IStructuralComparable
- {
- int CompareTo(object? other, IComparer comparer);
- }
- public interface IStructuralEquatable
- {
- bool Equals(object? other, IEqualityComparer comparer);
- int GetHashCode(IEqualityComparer comparer);
- }
-}
-#endif
-
-
-
-namespace System.Numerics.Hashing
-{
- internal static class HashHelpers
- {
- public static readonly int RandomSeed = Guid.NewGuid().GetHashCode();
-
- public static int Combine(int h1, int h2)
- {
- unchecked
- {
- // RyuJIT optimizes this to use the ROL instruction
- // Related GitHub pull request: dotnet/coreclr#1830
-
- // RyuJIT 对此进行了优化以使用 ROL 指令
- // 相关 GitHub 拉取请求:dotnet/coreclr#1830
- uint rol5 = ((uint)h1 << 5) | ((uint)h1 >> 27);
- return ((int)rol5 + h1) ^ h2;
- }
- }
- }
-}
-
-
-
-
-namespace System
-{
-
- // internal static class SR
- internal sealed partial class SR
- {
- // public const string ArgumentException_ValueTupleIncorrectType = "The parameter should be a ValueTuple type of appropriate arity.";
- // public const string ArgumentException_ValueTupleLastArgumentNotAValueTuple = "The TRest type argument of ValueTuple`8 must be a ValueTuple.";
- public const string ArgumentException_ValueTupleIncorrectType = "该参数应该是适当数量的 ValueTuple 类型.";
- public const string ArgumentException_ValueTupleLastArgumentNotAValueTuple = "ValueTuple`8 的 TREST 类型参数必须是 ValueTuple.";
- }
-
- // Helper so we can call some tuple methods recursively without knowing the underlying types.
- ///
- /// 帮助器,因此我们可以在不知道底层类型的情况下递归调用一些元组方法.
- ///
- internal interface ITupleInternal
- {
- int GetHashCode(IEqualityComparer comparer);
- int Size { get; }
- string ToStringEnd();
- }
-
-
- // The ValueTuple types (from arity 0 to 8) comprise the runtime implementation that underlies tuples in C# and struct tuples in F#.
- // Aside from created via language syntax, they are most easily created via the ValueTuple.Create factory methods.
- // The System.ValueTuple types differ from the System.Tuple types in that:
- // - they are structs rather than classes,
- // - they are mutable rather than readonly, and
- // - their members (such as Item1, Item2, etc) are fields rather than properties.
- ///
- /// ValueTuple 类型(从 arity 0 到 8)包含运行时实现,它是 C# 中的元组和 F# 中的结构元组的基础.
- /// 除了通过语言语法创建之外,它们最容易通过 ValueTuple.Create 工厂方法创建.
- /// System.ValueTuple 类型与 System.Tuple 类型的不同之处在于:
- /// - 它们是结构而不是类,
- /// - 它们是可变的而不是只读的,并且
- /// - 它们的成员(例如 Item1、Item2 等)是字段而不是属性.
- ///
- public struct ValueTuple
- : IEquatable, IStructuralEquatable, IStructuralComparable, IComparable, IComparable, ITupleInternal
- {
- ///
- /// Returns a value that indicates whether the current instance is equal to a specified object.
- ///
- /// The object to compare with this instance.
- /// if is a .
- public override bool Equals(object obj)
- {
- return obj is ValueTuple;
- }
-
- /// Returns a value indicating whether this instance is equal to a specified value.
- /// An instance to compare to this instance.
- /// true if has the same value as this instance; otherwise, false.
- public bool Equals(ValueTuple other)
- {
- return true;
- }
-
- bool IStructuralEquatable.Equals(object? other, IEqualityComparer comparer)
- {
- return other is ValueTuple;
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- return 0;
- }
-
- /// Compares this instance to a specified instance and returns an indication of their relative values.
- /// An instance to compare.
- ///
- /// A signed number indicating the relative values of this instance and .
- /// Returns less than zero if this instance is less than , zero if this
- /// instance is equal to , and greater than zero if this instance is greater
- /// than .
- ///
- public int CompareTo(ValueTuple other)
- {
- return 0;
- }
-
- int IStructuralComparable.CompareTo(object? other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- return 0;
- }
-
- /// Returns the hash code for this instance.
- /// A 32-bit signed integer hash code.
- public override int GetHashCode()
- {
- return 0;
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return 0;
- }
-
- int ITupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return 0;
- }
-
- ///
- /// Returns a string that represents the value of this instance.
- ///
- /// The string representation of this instance.
- ///
- /// The string returned by this method takes the form ().
- ///
- public override string ToString()
- {
- return "()";
- }
-
- string ITupleInternal.ToStringEnd()
- {
- return ")";
- }
-
- int ITupleInternal.Size => 0;
-
- /// Creates a new struct 0-tuple.
- /// A 0-tuple.
- public static ValueTuple Create() => new();
-
- /// Creates a new struct 1-tuple, or singleton.
- /// The type of the first component of the tuple.
- /// The value of the first component of the tuple.
- /// A 1-tuple (singleton) whose value is (item1).
- public static ValueTuple Create(T1 item1) => new(item1);
-
- /// Creates a new struct 2-tuple, or pair.
- /// The type of the first component of the tuple.
- /// The type of the second component of the tuple.
- /// The value of the first component of the tuple.
- /// The value of the second component of the tuple.
- /// A 2-tuple (pair) whose value is (item1, item2).
- public static ValueTuple Create(T1 item1, T2 item2) => new(item1, item2);
-
- /// Creates a new struct 3-tuple, or triple.
- /// The type of the first component of the tuple.
- /// The type of the second component of the tuple.
- /// The type of the third component of the tuple.
- /// The value of the first component of the tuple.
- /// The value of the second component of the tuple.
- /// The value of the third component of the tuple.
- /// A 3-tuple (triple) whose value is (item1, item2, item3).
- public static ValueTuple Create(T1 item1, T2 item2, T3 item3) =>
- new(item1, item2, item3);
-
- /// Creates a new struct 4-tuple, or quadruple.
- /// The type of the first component of the tuple.
- /// The type of the second component of the tuple.
- /// The type of the third component of the tuple.
- /// The type of the fourth component of the tuple.
- /// The value of the first component of the tuple.
- /// The value of the second component of the tuple.
- /// The value of the third component of the tuple.
- /// The value of the fourth component of the tuple.
- /// A 4-tuple (quadruple) whose value is (item1, item2, item3, item4).
- public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4) =>
- new(item1, item2, item3, item4);
-
- /// Creates a new struct 5-tuple, or quintuple.
- /// The type of the first component of the tuple.
- /// The type of the second component of the tuple.
- /// The type of the third component of the tuple.
- /// The type of the fourth component of the tuple.
- /// The type of the fifth component of the tuple.
- /// The value of the first component of the tuple.
- /// The value of the second component of the tuple.
- /// The value of the third component of the tuple.
- /// The value of the fourth component of the tuple.
- /// The value of the fifth component of the tuple.
- /// A 5-tuple (quintuple) whose value is (item1, item2, item3, item4, item5).
- public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) =>
- new(item1, item2, item3, item4, item5);
-
- /// Creates a new struct 6-tuple, or sextuple.
- /// The type of the first component of the tuple.
- /// The type of the second component of the tuple.
- /// The type of the third component of the tuple.
- /// The type of the fourth component of the tuple.
- /// The type of the fifth component of the tuple.
- /// The type of the sixth component of the tuple.
- /// The value of the first component of the tuple.
- /// The value of the second component of the tuple.
- /// The value of the third component of the tuple.
- /// The value of the fourth component of the tuple.
- /// The value of the fifth component of the tuple.
- /// The value of the sixth component of the tuple.
- /// A 6-tuple (sextuple) whose value is (item1, item2, item3, item4, item5, item6).
- public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) =>
- new(item1, item2, item3, item4, item5, item6);
-
- /// Creates a new struct 7-tuple, or septuple.
- /// The type of the first component of the tuple.
- /// The type of the second component of the tuple.
- /// The type of the third component of the tuple.
- /// The type of the fourth component of the tuple.
- /// The type of the fifth component of the tuple.
- /// The type of the sixth component of the tuple.
- /// The type of the seventh component of the tuple.
- /// The value of the first component of the tuple.
- /// The value of the second component of the tuple.
- /// The value of the third component of the tuple.
- /// The value of the fourth component of the tuple.
- /// The value of the fifth component of the tuple.
- /// The value of the sixth component of the tuple.
- /// The value of the seventh component of the tuple.
- /// A 7-tuple (septuple) whose value is (item1, item2, item3, item4, item5, item6, item7).
- public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) =>
- new(item1, item2, item3, item4, item5, item6, item7);
-
- /// Creates a new struct 8-tuple, or octuple.
- /// The type of the first component of the tuple.
- /// The type of the second component of the tuple.
- /// The type of the third component of the tuple.
- /// The type of the fourth component of the tuple.
- /// The type of the fifth component of the tuple.
- /// The type of the sixth component of the tuple.
- /// The type of the seventh component of the tuple.
- /// The type of the eighth component of the tuple.
- /// The value of the first component of the tuple.
- /// The value of the second component of the tuple.
- /// The value of the third component of the tuple.
- /// The value of the fourth component of the tuple.
- /// The value of the fifth component of the tuple.
- /// The value of the sixth component of the tuple.
- /// The value of the seventh component of the tuple.
- /// The value of the eighth component of the tuple.
- /// An 8-tuple (octuple) whose value is (item1, item2, item3, item4, item5, item6, item7, item8).
- public static ValueTuple> Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) =>
- new(item1, item2, item3, item4, item5, item6, item7, ValueTuple.Create(item8));
-
- internal static int CombineHashCodes(int h1, int h2)
- {
- return HashHelpers.Combine(HashHelpers.Combine(HashHelpers.RandomSeed, h1), h2);
- }
-
- internal static int CombineHashCodes(int h1, int h2, int h3)
- {
- return HashHelpers.Combine(CombineHashCodes(h1, h2), h3);
- }
-
- internal static int CombineHashCodes(int h1, int h2, int h3, int h4)
- {
- return HashHelpers.Combine(CombineHashCodes(h1, h2, h3), h4);
- }
-
- internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5)
- {
- return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4), h5);
- }
-
- internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6)
- {
- return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5), h6);
- }
-
- internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7)
- {
- return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6), h7);
- }
-
- internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8)
- {
- return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6, h7), h8);
- }
- }
-
- /// Represents a 1-tuple, or singleton, as a value type.
- /// The type of the tuple's only component.
- public struct ValueTuple
- : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal
- {
- ///
- /// The current instance's first component.
- ///
- public T1 Item1;
-
- ///
- /// Initializes a new instance of the value type.
- ///
- /// The value of the tuple's first component.
- public ValueTuple(T1 item1)
- {
- Item1 = item1;
- }
-
- ///
- /// Returns a value that indicates whether the current instance is equal to a specified object.
- ///
- /// The object to compare with this instance.
- /// if the current instance is equal to the specified object; otherwise, .
- ///
- /// The parameter is considered to be equal to the current instance under the following conditions:
- ///
- /// It is a value type.
- /// Its components are of the same types as those of the current instance.
- /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.
- ///
- ///
- public override bool Equals(object obj)
- {
- return obj is ValueTuple tuple && Equals(tuple);
- }
-
- ///
- /// Returns a value that indicates whether the current
- /// instance is equal to a specified .
- ///
- /// The tuple to compare with this instance.
- /// if the current instance is equal to the specified tuple; otherwise, .
- ///
- /// The parameter is considered to be equal to the current instance if each of its field
- /// is equal to that of the current instance, using the default comparer for that field's type.
- ///
- public bool Equals(ValueTuple other)
- {
- return EqualityComparer.Default.Equals(Item1, other.Item1);
- }
-
- bool IStructuralEquatable.Equals(object? other, IEqualityComparer comparer)
- {
- if (other == null || other is not ValueTuple) return false;
-
- var objTuple = (ValueTuple)other;
-
- return comparer.Equals(Item1, objTuple.Item1);
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- var objTuple = (ValueTuple)other;
-
- return Comparer.Default.Compare(Item1, objTuple.Item1);
- }
-
- /// Compares this instance to a specified instance and returns an indication of their relative values.
- /// An instance to compare.
- ///
- /// A signed number indicating the relative values of this instance and .
- /// Returns less than zero if this instance is less than , zero if this
- /// instance is equal to , and greater than zero if this instance is greater
- /// than .
- ///
- public int CompareTo(ValueTuple other)
- {
- return Comparer.Default.Compare(Item1, other.Item1);
- }
-
- int IStructuralComparable.CompareTo(object? other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- var objTuple = (ValueTuple)other;
-
- return comparer.Compare(Item1, objTuple.Item1);
- }
-
- ///
- /// Returns the hash code for the current instance.
- ///
- /// A 32-bit signed integer hash code.
- public override int GetHashCode()
- {
- return EqualityComparer.Default.GetHashCode(Item1);
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return comparer.GetHashCode(Item1);
- }
-
- int ITupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return comparer.GetHashCode(Item1);
- }
-
- ///
- /// Returns a string that represents the value of this instance.
- ///
- /// The string representation of this instance.
- ///
- /// The string returned by this method takes the form (Item1),
- /// where Item1 represents the value of . If the field is ,
- /// it is represented as .
- ///
- public override string ToString()
- {
- return "(" + Item1?.ToString() + ")";
- }
-
- string ITupleInternal.ToStringEnd()
- {
- return Item1?.ToString() + ")";
- }
-
- int ITupleInternal.Size => 1;
- }
-
- ///
- /// Represents a 2-tuple, or pair, as a value type.
- ///
- /// The type of the tuple's first component.
- /// The type of the tuple's second component.
- public struct ValueTuple
- : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal
- {
- ///
- /// The current instance's first component.
- ///
- public T1 Item1;
-
- ///
- /// The current instance's first component.
- ///
- public T2 Item2;
-
- ///
- /// Initializes a new instance of the value type.
- ///
- /// The value of the tuple's first component.
- /// The value of the tuple's second component.
- public ValueTuple(T1 item1, T2 item2)
- {
- Item1 = item1;
- Item2 = item2;
- }
-
- ///
- /// Returns a value that indicates whether the current instance is equal to a specified object.
- ///
- /// The object to compare with this instance.
- /// if the current instance is equal to the specified object; otherwise, .
- ///
- ///
- /// The parameter is considered to be equal to the current instance under the following conditions:
- ///
- /// It is a value type.
- /// Its components are of the same types as those of the current instance.
- /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.
- ///
- ///
- public override bool Equals(object obj)
- {
- return obj is ValueTuple tuple && Equals(tuple);
- }
-
- ///
- /// Returns a value that indicates whether the current instance is equal to a specified .
- ///
- /// The tuple to compare with this instance.
- /// if the current instance is equal to the specified tuple; otherwise, .
- ///
- /// The parameter is considered to be equal to the current instance if each of its fields
- /// are equal to that of the current instance, using the default comparer for that field's type.
- ///
- public bool Equals(ValueTuple other)
- {
- return EqualityComparer.Default.Equals(Item1, other.Item1)
- && EqualityComparer.Default.Equals(Item2, other.Item2);
- }
-
- ///
- /// Returns a value that indicates whether the current instance is equal to a specified object based on a specified comparison method.
- ///
- /// The object to compare with this instance.
- /// An object that defines the method to use to evaluate whether the two objects are equal.
- /// if the current instance is equal to the specified object; otherwise, .
- ///
- ///
- /// This member is an explicit interface member implementation. It can be used only when the
- /// instance is cast to an interface.
- ///
- /// The implementation is called only if other is not ,
- /// and if it can be successfully cast (in C#) or converted (in Visual Basic) to a
- /// whose components are of the same types as those of the current instance. The IStructuralEquatable.Equals(Object, IEqualityComparer) method
- /// first passes the values of the objects to be compared to the
- /// implementation. If this method call returns , the method is
- /// called again and passed the values of the two instances.
- ///
- bool IStructuralEquatable.Equals(object? other, IEqualityComparer comparer)
- {
- if (other is null or not ValueTuple) return false;
-
- var objTuple = (ValueTuple)other;
-
- return comparer.Equals(Item1, objTuple.Item1)
- && comparer.Equals(Item2, objTuple.Item2);
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- return CompareTo((ValueTuple)other);
- }
-
- /// Compares this instance to a specified instance and returns an indication of their relative values.
- /// An instance to compare.
- ///
- /// A signed number indicating the relative values of this instance and .
- /// Returns less than zero if this instance is less than , zero if this
- /// instance is equal to , and greater than zero if this instance is greater
- /// than .
- ///
- public int CompareTo(ValueTuple other)
- {
- int c = Comparer.Default.Compare(Item1, other.Item1);
- if (c != 0) return c;
-
- return Comparer.Default.Compare(Item2, other.Item2);
- }
-
- int IStructuralComparable.CompareTo(object? other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- var objTuple = (ValueTuple)other;
-
- int c = comparer.Compare(Item1, objTuple.Item1);
- if (c != 0) return c;
-
- return comparer.Compare(Item2, objTuple.Item2);
- }
-
- ///
- /// Returns the hash code for the current instance.
- ///
- /// A 32-bit signed integer hash code.
- public override int GetHashCode()
- {
- return ValueTuple.CombineHashCodes(EqualityComparer.Default.GetHashCode(Item1),
- EqualityComparer.Default.GetHashCode(Item2));
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- private int GetHashCodeCore(IEqualityComparer comparer)
- {
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
- comparer.GetHashCode(Item2));
- }
-
- int ITupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- ///
- /// Returns a string that represents the value of this instance.
- ///
- /// The string representation of this instance.
- ///
- /// The string returned by this method takes the form (Item1, Item2),
- /// where Item1 and Item2 represent the values of the
- /// and fields. If either field value is ,
- /// it is represented as .
- ///
- public override string ToString()
- {
- return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ")";
- }
-
- string ITupleInternal.ToStringEnd()
- {
- return Item1?.ToString() + ", " + Item2?.ToString() + ")";
- }
-
- int ITupleInternal.Size => 2;
- }
-
- ///
- /// Represents a 3-tuple, or triple, as a value type.
- ///
- /// The type of the tuple's first component.
- /// The type of the tuple's second component.
- /// The type of the tuple's third component.
- public struct ValueTuple
- : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal
- {
- ///
- /// The current instance's first component.
- ///
- public T1 Item1;
- ///
- /// The current instance's second component.
- ///
- public T2 Item2;
- ///
- /// The current instance's third component.
- ///
- public T3 Item3;
-
- ///
- /// Initializes a new instance of the value type.
- ///
- /// The value of the tuple's first component.
- /// The value of the tuple's second component.
- /// The value of the tuple's third component.
- public ValueTuple(T1 item1, T2 item2, T3 item3)
- {
- Item1 = item1;
- Item2 = item2;
- Item3 = item3;
- }
-
- ///
- /// Returns a value that indicates whether the current instance is equal to a specified object.
- ///
- /// The object to compare with this instance.
- /// if the current instance is equal to the specified object; otherwise, .
- ///
- /// The parameter is considered to be equal to the current instance under the following conditions:
- ///
- /// It is a value type.
- /// Its components are of the same types as those of the current instance.
- /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.
- ///
- ///
- public override bool Equals(object obj)
- {
- return obj is ValueTuple tuple && Equals(tuple);
- }
-
- ///
- /// Returns a value that indicates whether the current
- /// instance is equal to a specified .
- ///
- /// The tuple to compare with this instance.
- /// if the current instance is equal to the specified tuple; otherwise, .
- ///
- /// The parameter is considered to be equal to the current instance if each of its fields
- /// are equal to that of the current instance, using the default comparer for that field's type.
- ///
- public bool Equals(ValueTuple other)
- {
- return EqualityComparer.Default.Equals(Item1, other.Item1)
- && EqualityComparer.Default.Equals(Item2, other.Item2)
- && EqualityComparer.Default.Equals(Item3, other.Item3);
- }
-
- bool IStructuralEquatable.Equals(object? other, IEqualityComparer comparer)
- {
- if (other == null || other is not ValueTuple) return false;
-
- var objTuple = (ValueTuple)other;
-
- return comparer.Equals(Item1, objTuple.Item1)
- && comparer.Equals(Item2, objTuple.Item2)
- && comparer.Equals(Item3, objTuple.Item3);
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- return CompareTo((ValueTuple)other);
- }
-
- /// Compares this instance to a specified instance and returns an indication of their relative values.
- /// An instance to compare.
- ///
- /// A signed number indicating the relative values of this instance and .
- /// Returns less than zero if this instance is less than , zero if this
- /// instance is equal to , and greater than zero if this instance is greater
- /// than .
- ///
- public int CompareTo(ValueTuple other)
- {
- int c = Comparer.Default.Compare(Item1, other.Item1);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item2, other.Item2);
- if (c != 0) return c;
-
- return Comparer.Default.Compare(Item3, other.Item3);
- }
-
- int IStructuralComparable.CompareTo(object? other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- var objTuple = (ValueTuple)other;
-
- int c = comparer.Compare(Item1, objTuple.Item1);
- if (c != 0) return c;
-
- c = comparer.Compare(Item2, objTuple.Item2);
- if (c != 0) return c;
-
- return comparer.Compare(Item3, objTuple.Item3);
- }
-
- ///
- /// Returns the hash code for the current instance.
- ///
- /// A 32-bit signed integer hash code.
- public override int GetHashCode()
- {
- return ValueTuple.CombineHashCodes(EqualityComparer.Default.GetHashCode(Item1),
- EqualityComparer.Default.GetHashCode(Item2),
- EqualityComparer.Default.GetHashCode(Item3));
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- private int GetHashCodeCore(IEqualityComparer comparer)
- {
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
- comparer.GetHashCode(Item2),
- comparer.GetHashCode(Item3));
- }
-
- int ITupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- ///
- /// Returns a string that represents the value of this instance.
- ///
- /// The string representation of this instance.
- ///
- /// The string returned by this method takes the form (Item1, Item2, Item3).
- /// If any field value is , it is represented as .
- ///
- public override string ToString()
- {
- return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")";
- }
-
- string ITupleInternal.ToStringEnd()
- {
- return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")";
- }
-
- int ITupleInternal.Size => 3;
- }
-
- ///
- /// Represents a 4-tuple, or quadruple, as a value type.
- ///
- /// The type of the tuple's first component.
- /// The type of the tuple's second component.
- /// The type of the tuple's third component.
- /// The type of the tuple's fourth component.
- public struct ValueTuple
- : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal
- {
- ///
- /// The current instance's first component.
- ///
- public T1 Item1;
- ///
- /// The current instance's second component.
- ///
- public T2 Item2;
- ///
- /// The current instance's third component.
- ///
- public T3 Item3;
- ///
- /// The current instance's fourth component.
- ///
- public T4 Item4;
-
- ///
- /// Initializes a new instance of the value type.
- ///
- /// The value of the tuple's first component.
- /// The value of the tuple's second component.
- /// The value of the tuple's third component.
- /// The value of the tuple's fourth component.
- public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4)
- {
- Item1 = item1;
- Item2 = item2;
- Item3 = item3;
- Item4 = item4;
- }
-
- ///
- /// Returns a value that indicates whether the current instance is equal to a specified object.
- ///
- /// The object to compare with this instance.
- /// if the current instance is equal to the specified object; otherwise, .
- ///
- /// The parameter is considered to be equal to the current instance under the following conditions:
- ///
- /// It is a value type.
- /// Its components are of the same types as those of the current instance.
- /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.
- ///
- ///
- public override bool Equals(object obj)
- {
- return obj is ValueTuple tuple && Equals(tuple);
- }
-
- ///
- /// Returns a value that indicates whether the current
- /// instance is equal to a specified .
- ///
- /// The tuple to compare with this instance.
- /// if the current instance is equal to the specified tuple; otherwise, .
- ///
- /// The parameter is considered to be equal to the current instance if each of its fields
- /// are equal to that of the current instance, using the default comparer for that field's type.
- ///
- public bool Equals(ValueTuple other)
- {
- return EqualityComparer.Default.Equals(Item1, other.Item1)
- && EqualityComparer.Default.Equals(Item2, other.Item2)
- && EqualityComparer.Default.Equals(Item3, other.Item3)
- && EqualityComparer.Default.Equals(Item4, other.Item4);
- }
-
- bool IStructuralEquatable.Equals(object? other, IEqualityComparer comparer)
- {
- if (other == null || other is not ValueTuple) return false;
-
- var objTuple = (ValueTuple)other;
-
- return comparer.Equals(Item1, objTuple.Item1)
- && comparer.Equals(Item2, objTuple.Item2)
- && comparer.Equals(Item3, objTuple.Item3)
- && comparer.Equals(Item4, objTuple.Item4);
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- return CompareTo((ValueTuple)other);
- }
-
- /// Compares this instance to a specified instance and returns an indication of their relative values.
- /// An instance to compare.
- ///
- /// A signed number indicating the relative values of this instance and .
- /// Returns less than zero if this instance is less than , zero if this
- /// instance is equal to , and greater than zero if this instance is greater
- /// than .
- ///
- public int CompareTo(ValueTuple other)
- {
- int c = Comparer.Default.Compare(Item1, other.Item1);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item2, other.Item2);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item3, other.Item3);
- if (c != 0) return c;
-
- return Comparer.Default.Compare(Item4, other.Item4);
- }
-
- int IStructuralComparable.CompareTo(object? other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- var objTuple = (ValueTuple)other;
-
- int c = comparer.Compare(Item1, objTuple.Item1);
- if (c != 0) return c;
-
- c = comparer.Compare(Item2, objTuple.Item2);
- if (c != 0) return c;
-
- c = comparer.Compare(Item3, objTuple.Item3);
- if (c != 0) return c;
-
- return comparer.Compare(Item4, objTuple.Item4);
- }
-
- ///
- /// Returns the hash code for the current instance.
- ///
- /// A 32-bit signed integer hash code.
- public override int GetHashCode()
- {
- return ValueTuple.CombineHashCodes(EqualityComparer.Default.GetHashCode(Item1),
- EqualityComparer.Default.GetHashCode(Item2),
- EqualityComparer.Default.GetHashCode(Item3),
- EqualityComparer.Default.GetHashCode(Item4));
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- private int GetHashCodeCore(IEqualityComparer comparer)
- {
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
- comparer.GetHashCode(Item2),
- comparer.GetHashCode(Item3),
- comparer.GetHashCode(Item4));
- }
-
- int ITupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- ///
- /// Returns a string that represents the value of this instance.
- ///
- /// The string representation of this instance.
- ///
- /// The string returned by this method takes the form (Item1, Item2, Item3, Item4).
- /// If any field value is , it is represented as .
- ///
- public override string ToString()
- {
- return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")";
- }
-
- string ITupleInternal.ToStringEnd()
- {
- return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")";
- }
-
- int ITupleInternal.Size => 4;
- }
-
- ///
- /// Represents a 5-tuple, or quintuple, as a value type.
- ///
- /// The type of the tuple's first component.
- /// The type of the tuple's second component.
- /// The type of the tuple's third component.
- /// The type of the tuple's fourth component.
- /// The type of the tuple's fifth component.
- public struct ValueTuple
- : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal
- {
- ///
- /// The current instance's first component.
- ///
- public T1 Item1;
- ///
- /// The current instance's second component.
- ///
- public T2 Item2;
- ///
- /// The current instance's third component.
- ///
- public T3 Item3;
- ///
- /// The current instance's fourth component.
- ///
- public T4 Item4;
- ///
- /// The current instance's fifth component.
- ///
- public T5 Item5;
-
- ///
- /// Initializes a new instance of the value type.
- ///
- /// The value of the tuple's first component.
- /// The value of the tuple's second component.
- /// The value of the tuple's third component.
- /// The value of the tuple's fourth component.
- /// The value of the tuple's fifth component.
- public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
- {
- Item1 = item1;
- Item2 = item2;
- Item3 = item3;
- Item4 = item4;
- Item5 = item5;
- }
-
- ///
- /// Returns a value that indicates whether the current instance is equal to a specified object.
- ///
- /// The object to compare with this instance.
- /// if the current instance is equal to the specified object; otherwise, .
- ///
- /// The parameter is considered to be equal to the current instance under the following conditions:
- ///
- /// It is a value type.
- /// Its components are of the same types as those of the current instance.
- /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.
- ///
- ///
- public override bool Equals(object obj)
- {
- return obj is ValueTuple tuple && Equals(tuple);
- }
-
- ///
- /// Returns a value that indicates whether the current
- /// instance is equal to a specified .
- ///
- /// The tuple to compare with this instance.
- /// if the current instance is equal to the specified tuple; otherwise, .
- ///
- /// The parameter is considered to be equal to the current instance if each of its fields
- /// are equal to that of the current instance, using the default comparer for that field's type.
- ///
- public bool Equals(ValueTuple other)
- {
- return EqualityComparer.Default.Equals(Item1, other.Item1)
- && EqualityComparer.Default.Equals(Item2, other.Item2)
- && EqualityComparer.Default.Equals(Item3, other.Item3)
- && EqualityComparer.Default.Equals(Item4, other.Item4)
- && EqualityComparer.Default.Equals(Item5, other.Item5);
- }
-
- bool IStructuralEquatable.Equals(object? other, IEqualityComparer comparer)
- {
- if (other == null || other is not ValueTuple) return false;
-
- var objTuple = (ValueTuple)other;
-
- return comparer.Equals(Item1, objTuple.Item1)
- && comparer.Equals(Item2, objTuple.Item2)
- && comparer.Equals(Item3, objTuple.Item3)
- && comparer.Equals(Item4, objTuple.Item4)
- && comparer.Equals(Item5, objTuple.Item5);
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- return CompareTo((ValueTuple)other);
- }
-
- /// Compares this instance to a specified instance and returns an indication of their relative values.
- /// An instance to compare.
- ///
- /// A signed number indicating the relative values of this instance and .
- /// Returns less than zero if this instance is less than , zero if this
- /// instance is equal to , and greater than zero if this instance is greater
- /// than .
- ///
- public int CompareTo(ValueTuple other)
- {
- int c = Comparer.Default.Compare(Item1, other.Item1);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item2, other.Item2);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item3, other.Item3);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item4, other.Item4);
- if (c != 0) return c;
-
- return Comparer.Default.Compare(Item5, other.Item5);
- }
-
- int IStructuralComparable.CompareTo(object? other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- var objTuple = (ValueTuple)other;
-
- int c = comparer.Compare(Item1, objTuple.Item1);
- if (c != 0) return c;
-
- c = comparer.Compare(Item2, objTuple.Item2);
- if (c != 0) return c;
-
- c = comparer.Compare(Item3, objTuple.Item3);
- if (c != 0) return c;
-
- c = comparer.Compare(Item4, objTuple.Item4);
- if (c != 0) return c;
-
- return comparer.Compare(Item5, objTuple.Item5);
- }
-
- ///
- /// Returns the hash code for the current instance.
- ///
- /// A 32-bit signed integer hash code.
- public override int GetHashCode()
- {
- return ValueTuple.CombineHashCodes(EqualityComparer.Default.GetHashCode(Item1),
- EqualityComparer.Default.GetHashCode(Item2),
- EqualityComparer.Default.GetHashCode(Item3),
- EqualityComparer.Default.GetHashCode(Item4),
- EqualityComparer.Default.GetHashCode(Item5));
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- private int GetHashCodeCore(IEqualityComparer comparer)
- {
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
- comparer.GetHashCode(Item2),
- comparer.GetHashCode(Item3),
- comparer.GetHashCode(Item4),
- comparer.GetHashCode(Item5));
- }
-
- int ITupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- ///
- /// Returns a string that represents the value of this instance.
- ///
- /// The string representation of this instance.
- ///
- /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5).
- /// If any field value is , it is represented as .
- ///
- public override string ToString()
- {
- return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")";
- }
-
- string ITupleInternal.ToStringEnd()
- {
- return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")";
- }
-
- int ITupleInternal.Size => 5;
- }
-
- ///
- /// Represents a 6-tuple, or sixtuple, as a value type.
- ///
- /// The type of the tuple's first component.
- /// The type of the tuple's second component.
- /// The type of the tuple's third component.
- /// The type of the tuple's fourth component.
- /// The type of the tuple's fifth component.
- /// The type of the tuple's sixth component.
- public struct ValueTuple
- : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal
- {
- ///
- /// The current instance's first component.
- ///
- public T1 Item1;
- ///
- /// The current instance's second component.
- ///
- public T2 Item2;
- ///
- /// The current instance's third component.
- ///
- public T3 Item3;
- ///
- /// The current instance's fourth component.
- ///
- public T4 Item4;
- ///
- /// The current instance's fifth component.
- ///
- public T5 Item5;
- ///
- /// The current instance's sixth component.
- ///
- public T6 Item6;
-
- ///
- /// Initializes a new instance of the value type.
- ///
- /// The value of the tuple's first component.
- /// The value of the tuple's second component.
- /// The value of the tuple's third component.
- /// The value of the tuple's fourth component.
- /// The value of the tuple's fifth component.
- /// The value of the tuple's sixth component.
- public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
- {
- Item1 = item1;
- Item2 = item2;
- Item3 = item3;
- Item4 = item4;
- Item5 = item5;
- Item6 = item6;
- }
-
- ///
- /// Returns a value that indicates whether the current instance is equal to a specified object.
- ///
- /// The object to compare with this instance.
- /// if the current instance is equal to the specified object; otherwise, .
- ///
- /// The parameter is considered to be equal to the current instance under the following conditions:
- ///
- /// It is a value type.
- /// Its components are of the same types as those of the current instance.
- /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.
- ///
- ///
- public override bool Equals(object obj)
- {
- return obj is ValueTuple tuple && Equals(tuple);
- }
-
- ///
- /// Returns a value that indicates whether the current
- /// instance is equal to a specified .
- ///
- /// The tuple to compare with this instance.
- /// if the current instance is equal to the specified tuple; otherwise, .
- ///
- /// The parameter is considered to be equal to the current instance if each of its fields
- /// are equal to that of the current instance, using the default comparer for that field's type.
- ///
- public bool Equals(ValueTuple other)
- {
- return EqualityComparer.Default.Equals(Item1, other.Item1)
- && EqualityComparer.Default.Equals(Item2, other.Item2)
- && EqualityComparer.Default.Equals(Item3, other.Item3)
- && EqualityComparer.Default.Equals(Item4, other.Item4)
- && EqualityComparer.Default.Equals(Item5, other.Item5)
- && EqualityComparer.Default.Equals(Item6, other.Item6);
- }
-
- bool IStructuralEquatable.Equals(object? other, IEqualityComparer comparer)
- {
- if (other == null || other is not ValueTuple) return false;
-
- var objTuple = (ValueTuple)other;
-
- return comparer.Equals(Item1, objTuple.Item1)
- && comparer.Equals(Item2, objTuple.Item2)
- && comparer.Equals(Item3, objTuple.Item3)
- && comparer.Equals(Item4, objTuple.Item4)
- && comparer.Equals(Item5, objTuple.Item5)
- && comparer.Equals(Item6, objTuple.Item6);
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- return CompareTo((ValueTuple)other);
- }
-
- /// Compares this instance to a specified instance and returns an indication of their relative values.
- /// An instance to compare.
- ///
- /// A signed number indicating the relative values of this instance and .
- /// Returns less than zero if this instance is less than , zero if this
- /// instance is equal to , and greater than zero if this instance is greater
- /// than .
- ///
- public int CompareTo(ValueTuple other)
- {
- int c = Comparer.Default.Compare(Item1, other.Item1);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item2, other.Item2);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item3, other.Item3);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item4, other.Item4);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item5, other.Item5);
- if (c != 0) return c;
-
- return Comparer.Default.Compare(Item6, other.Item6);
- }
-
- int IStructuralComparable.CompareTo(object? other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- var objTuple = (ValueTuple)other;
-
- int c = comparer.Compare(Item1, objTuple.Item1);
- if (c != 0) return c;
-
- c = comparer.Compare(Item2, objTuple.Item2);
- if (c != 0) return c;
-
- c = comparer.Compare(Item3, objTuple.Item3);
- if (c != 0) return c;
-
- c = comparer.Compare(Item4, objTuple.Item4);
- if (c != 0) return c;
-
- c = comparer.Compare(Item5, objTuple.Item5);
- if (c != 0) return c;
-
- return comparer.Compare(Item6, objTuple.Item6);
- }
-
- ///
- /// Returns the hash code for the current instance.
- ///
- /// A 32-bit signed integer hash code.
- public override int GetHashCode()
- {
- return ValueTuple.CombineHashCodes(EqualityComparer.Default.GetHashCode(Item1),
- EqualityComparer.Default.GetHashCode(Item2),
- EqualityComparer.Default.GetHashCode(Item3),
- EqualityComparer.Default.GetHashCode(Item4),
- EqualityComparer.Default.GetHashCode(Item5),
- EqualityComparer.Default.GetHashCode(Item6));
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- private int GetHashCodeCore(IEqualityComparer comparer)
- {
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
- comparer.GetHashCode(Item2),
- comparer.GetHashCode(Item3),
- comparer.GetHashCode(Item4),
- comparer.GetHashCode(Item5),
- comparer.GetHashCode(Item6));
- }
-
- int ITupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- ///
- /// Returns a string that represents the value of this instance.
- ///
- /// The string representation of this instance.
- ///
- /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6).
- /// If any field value is , it is represented as .
- ///
- public override string ToString()
- {
- return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")";
- }
-
- string ITupleInternal.ToStringEnd()
- {
- return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")";
- }
-
- int ITupleInternal.Size => 6;
- }
-
- ///
- /// Represents a 7-tuple, or sentuple, as a value type.
- ///
- /// The type of the tuple's first component.
- /// The type of the tuple's second component.
- /// The type of the tuple's third component.
- /// The type of the tuple's fourth component.
- /// The type of the tuple's fifth component.
- /// The type of the tuple's sixth component.
- /// The type of the tuple's seventh component.
- public struct ValueTuple
- : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal
- {
- ///
- /// The current instance's first component.
- ///
- public T1 Item1;
- ///
- /// The current instance's second component.
- ///
- public T2 Item2;
- ///
- /// The current instance's third component.
- ///
- public T3 Item3;
- ///
- /// The current instance's fourth component.
- ///
- public T4 Item4;
- ///
- /// The current instance's fifth component.
- ///
- public T5 Item5;
- ///
- /// The current instance's sixth component.
- ///
- public T6 Item6;
- ///
- /// The current instance's seventh component.
- ///
- public T7 Item7;
-
- ///
- /// Initializes a new instance of the value type.
- ///
- /// The value of the tuple's first component.
- /// The value of the tuple's second component.
- /// The value of the tuple's third component.
- /// The value of the tuple's fourth component.
- /// The value of the tuple's fifth component.
- /// The value of the tuple's sixth component.
- /// The value of the tuple's seventh component.
- public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
- {
- Item1 = item1;
- Item2 = item2;
- Item3 = item3;
- Item4 = item4;
- Item5 = item5;
- Item6 = item6;
- Item7 = item7;
- }
-
- ///
- /// Returns a value that indicates whether the current instance is equal to a specified object.
- ///
- /// The object to compare with this instance.
- /// if the current instance is equal to the specified object; otherwise, .
- ///
- /// The parameter is considered to be equal to the current instance under the following conditions:
- ///
- /// It is a value type.
- /// Its components are of the same types as those of the current instance.
- /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.
- ///
- ///
- public override bool Equals(object obj)
- {
- return obj is ValueTuple tuple && Equals(tuple);
- }
-
- ///
- /// Returns a value that indicates whether the current
- /// instance is equal to a specified .
- ///
- /// The tuple to compare with this instance.
- /// if the current instance is equal to the specified tuple; otherwise, .
- ///
- /// The parameter is considered to be equal to the current instance if each of its fields
- /// are equal to that of the current instance, using the default comparer for that field's type.
- ///
- public bool Equals(ValueTuple other)
- {
- return EqualityComparer.Default.Equals(Item1, other.Item1)
- && EqualityComparer.Default.Equals(Item2, other.Item2)
- && EqualityComparer.Default.Equals(Item3, other.Item3)
- && EqualityComparer.Default.Equals(Item4, other.Item4)
- && EqualityComparer.Default.Equals(Item5, other.Item5)
- && EqualityComparer.Default.Equals(Item6, other.Item6)
- && EqualityComparer.Default.Equals(Item7, other.Item7);
- }
-
- bool IStructuralEquatable.Equals(object? other, IEqualityComparer comparer)
- {
- if (other == null || other is not ValueTuple) return false;
-
- var objTuple = (ValueTuple)other;
-
- return comparer.Equals(Item1, objTuple.Item1)
- && comparer.Equals(Item2, objTuple.Item2)
- && comparer.Equals(Item3, objTuple.Item3)
- && comparer.Equals(Item4, objTuple.Item4)
- && comparer.Equals(Item5, objTuple.Item5)
- && comparer.Equals(Item6, objTuple.Item6)
- && comparer.Equals(Item7, objTuple.Item7);
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- return CompareTo((ValueTuple)other);
- }
-
- /// Compares this instance to a specified instance and returns an indication of their relative values.
- /// An instance to compare.
- ///
- /// A signed number indicating the relative values of this instance and .
- /// Returns less than zero if this instance is less than , zero if this
- /// instance is equal to , and greater than zero if this instance is greater
- /// than .
- ///
- public int CompareTo(ValueTuple other)
- {
- int c = Comparer.Default.Compare(Item1, other.Item1);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item2, other.Item2);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item3, other.Item3);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item4, other.Item4);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item5, other.Item5);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item6, other.Item6);
- if (c != 0) return c;
-
- return Comparer.Default.Compare(Item7, other.Item7);
- }
-
- int IStructuralComparable.CompareTo(object? other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- var objTuple = (ValueTuple)other;
-
- int c = comparer.Compare(Item1, objTuple.Item1);
- if (c != 0) return c;
-
- c = comparer.Compare(Item2, objTuple.Item2);
- if (c != 0) return c;
-
- c = comparer.Compare(Item3, objTuple.Item3);
- if (c != 0) return c;
-
- c = comparer.Compare(Item4, objTuple.Item4);
- if (c != 0) return c;
-
- c = comparer.Compare(Item5, objTuple.Item5);
- if (c != 0) return c;
-
- c = comparer.Compare(Item6, objTuple.Item6);
- if (c != 0) return c;
-
- return comparer.Compare(Item7, objTuple.Item7);
- }
-
- ///
- /// Returns the hash code for the current instance.
- ///
- /// A 32-bit signed integer hash code.
- public override int GetHashCode()
- {
- return ValueTuple.CombineHashCodes(EqualityComparer.Default.GetHashCode(Item1),
- EqualityComparer.Default.GetHashCode(Item2),
- EqualityComparer.Default.GetHashCode(Item3),
- EqualityComparer.Default.GetHashCode(Item4),
- EqualityComparer.Default.GetHashCode(Item5),
- EqualityComparer.Default.GetHashCode(Item6),
- EqualityComparer.Default.GetHashCode(Item7));
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- private int GetHashCodeCore(IEqualityComparer comparer)
- {
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
- comparer.GetHashCode(Item2),
- comparer.GetHashCode(Item3),
- comparer.GetHashCode(Item4),
- comparer.GetHashCode(Item5),
- comparer.GetHashCode(Item6),
- comparer.GetHashCode(Item7));
- }
-
- int ITupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- ///
- /// Returns a string that represents the value of this instance.
- ///
- /// The string representation of this instance.
- ///
- /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6, Item7).
- /// If any field value is , it is represented as .
- ///
- public override string ToString()
- {
- return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")";
- }
-
- string ITupleInternal.ToStringEnd()
- {
- return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")";
- }
-
- int ITupleInternal.Size => 7;
- }
-
- ///
- /// Represents an 8-tuple, or octuple, as a value type.
- ///
- /// The type of the tuple's first component.
- /// The type of the tuple's second component.
- /// The type of the tuple's third component.
- /// The type of the tuple's fourth component.
- /// The type of the tuple's fifth component.
- /// The type of the tuple's sixth component.
- /// The type of the tuple's seventh component.
- /// The type of the tuple's eighth component.
- public struct ValueTuple
- : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal
- where TRest : struct
- {
- ///
- /// The current instance's first component.
- ///
- public T1 Item1;
- ///
- /// The current instance's second component.
- ///
- public T2 Item2;
- ///
- /// The current instance's third component.
- ///
- public T3 Item3;
- ///
- /// The current instance's fourth component.
- ///
- public T4 Item4;
- ///
- /// The current instance's fifth component.
- ///
- public T5 Item5;
- ///
- /// The current instance's sixth component.
- ///
- public T6 Item6;
- ///
- /// The current instance's seventh component.
- ///
- public T7 Item7;
- ///
- /// The current instance's eighth component.
- ///
- public TRest Rest;
-
- ///
- /// Initializes a new instance of the value type.
- ///
- /// The value of the tuple's first component.
- /// The value of the tuple's second component.
- /// The value of the tuple's third component.
- /// The value of the tuple's fourth component.
- /// The value of the tuple's fifth component.
- /// The value of the tuple's sixth component.
- /// The value of the tuple's seventh component.
- /// The value of the tuple's eight component.
- public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest)
- {
- if (rest is not ITupleInternal)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleLastArgumentNotAValueTuple);
- }
-
- Item1 = item1;
- Item2 = item2;
- Item3 = item3;
- Item4 = item4;
- Item5 = item5;
- Item6 = item6;
- Item7 = item7;
- Rest = rest;
- }
-
- ///
- /// Returns a value that indicates whether the current instance is equal to a specified object.
- ///
- /// The object to compare with this instance.
- /// if the current instance is equal to the specified object; otherwise, .
- ///
- /// The parameter is considered to be equal to the current instance under the following conditions:
- ///
- /// It is a value type.
- /// Its components are of the same types as those of the current instance.
- /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.
- ///
- ///
- public override bool Equals(object obj)
- {
- return obj is ValueTuple tuple && Equals(tuple);
- }
-
- ///
- /// Returns a value that indicates whether the current
- /// instance is equal to a specified .
- ///
- /// The tuple to compare with this instance.
- /// if the current instance is equal to the specified tuple; otherwise, .
- ///
- /// The parameter is considered to be equal to the current instance if each of its fields
- /// are equal to that of the current instance, using the default comparer for that field's type.
- ///
- public bool Equals(ValueTuple other)
- {
- return EqualityComparer.Default.Equals(Item1, other.Item1)
- && EqualityComparer.Default.Equals(Item2, other.Item2)
- && EqualityComparer.Default.Equals(Item3, other.Item3)
- && EqualityComparer.Default.Equals(Item4, other.Item4)
- && EqualityComparer.Default.Equals(Item5, other.Item5)
- && EqualityComparer.Default.Equals(Item6, other.Item6)
- && EqualityComparer.Default.Equals(Item7, other.Item7)
- && EqualityComparer.Default.Equals(Rest, other.Rest);
- }
-
- bool IStructuralEquatable.Equals(object? other, IEqualityComparer comparer)
- {
- if (other == null || other is not ValueTuple) return false;
-
- var objTuple = (ValueTuple)other;
-
- return comparer.Equals(Item1, objTuple.Item1)
- && comparer.Equals(Item2, objTuple.Item2)
- && comparer.Equals(Item3, objTuple.Item3)
- && comparer.Equals(Item4, objTuple.Item4)
- && comparer.Equals(Item5, objTuple.Item5)
- && comparer.Equals(Item6, objTuple.Item6)
- && comparer.Equals(Item7, objTuple.Item7)
- && comparer.Equals(Rest, objTuple.Rest);
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- return CompareTo((ValueTuple)other);
- }
-
- /// Compares this instance to a specified instance and returns an indication of their relative values.
- /// An instance to compare.
- ///
- /// A signed number indicating the relative values of this instance and .
- /// Returns less than zero if this instance is less than , zero if this
- /// instance is equal to , and greater than zero if this instance is greater
- /// than .
- ///
- public int CompareTo(ValueTuple other)
- {
- int c = Comparer.Default.Compare(Item1, other.Item1);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item2, other.Item2);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item3, other.Item3);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item4, other.Item4);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item5, other.Item5);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item6, other.Item6);
- if (c != 0) return c;
-
- c = Comparer.Default.Compare(Item7, other.Item7);
- if (c != 0) return c;
-
- return Comparer.Default.Compare(Rest, other.Rest);
- }
-
- int IStructuralComparable.CompareTo(object? other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (other is not ValueTuple)
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, nameof(other));
- }
-
- var objTuple = (ValueTuple)other;
-
- int c = comparer.Compare(Item1, objTuple.Item1);
- if (c != 0) return c;
-
- c = comparer.Compare(Item2, objTuple.Item2);
- if (c != 0) return c;
-
- c = comparer.Compare(Item3, objTuple.Item3);
- if (c != 0) return c;
-
- c = comparer.Compare(Item4, objTuple.Item4);
- if (c != 0) return c;
-
- c = comparer.Compare(Item5, objTuple.Item5);
- if (c != 0) return c;
-
- c = comparer.Compare(Item6, objTuple.Item6);
- if (c != 0) return c;
-
- c = comparer.Compare(Item7, objTuple.Item7);
- if (c != 0) return c;
-
- return comparer.Compare(Rest, objTuple.Rest);
- }
-
- ///
- /// Returns the hash code for the current instance.
- ///
- /// A 32-bit signed integer hash code.
- public override int GetHashCode()
- {
- // We want to have a limited hash in this case. We'll use the last 8 elements of the tuple
- if (Rest is not ITupleInternal rest)
- {
- return ValueTuple.CombineHashCodes(EqualityComparer.Default.GetHashCode(Item1),
- EqualityComparer.Default.GetHashCode(Item2),
- EqualityComparer.Default.GetHashCode(Item3),
- EqualityComparer.Default.GetHashCode(Item4),
- EqualityComparer.Default.GetHashCode(Item5),
- EqualityComparer