结构对 return 以结构化方式来自函数的数据有意义吗? (什么时候结构合适?)
Does a struct make sense to return Data from a function in a structured way? (when is a struct apropriate?)
简介
到目前为止,我正在尝试围绕结构进行思考。我在“何时使用结构”这一主题上找到了很多答案。他们中的大多数都含糊不清,例如一般情况下反对使用结构的建议,只有少数例外。有关于何时使用结构的解释(几个例子):
- 不可变数据
- 与引用语义相反的值语义
- 在传递结构化数据的代码中需要它们 to/from C/C++
- 除非需要,否则不要使用结构
但是没有示例代码说明这种情况实际发生的时间是有意义的。
最有名的 Questions/Answers 可能是这个:
When should I use a struct rather than a class in C#?
项目结构
class StorageBlock<Type>
:
/// this is a storage block. It is not a struct because the data is not immutable and it
/// should be passed by reference
public class StorageBlock<Type>
{
Type[] Data;
/* other stuff */
}
方法BlockSearcher()
:
public (StorageBlock<Type> FoundBlock, int FoundIndex) SearchBlock(Type searchForThisElement)
{
StorageBlock<Type> found = Blocks.Find(searchForThisElement);
int index = Array.IndexOf(found.Data, searchForThisElement);
return (found,index);
}
来电者示例:
(StorageBlock<Type> FoundBlock, int FoundIndex) searchResult = SearchBlock(searchElement);
/* process SearchResult(s) */
问题
我想知道将 (StorageBlock<Type> FoundBlock, int FoundIndex) searchResult
转换为结构是否有意义。搜索结果应该是不可变的。它只是为了提供来自特定索引操作的 return。
像这样:
struct BlockIndex
{
StorageBlock<Type> Block;
int Index;
}
因为结构是数据类型,而不是引用类型,我还想知道 BlockIndex.Block
(这是一个 class)是否会引用块的实例或找到方块。
您似乎是在将结构与元组(编译为 ValueTuple
,而不是 Tuple
)进行比较,而不是将结构与 类(这是更常见的问题和原始建议的上下文)。使用该语法定义元组是 C# 中较新的构造,因此我不知道是否有关于是显式定义结构还是使用元组的最佳实践。
Behind-the-scenes,元组被实现为 ValueTuple
结构,因此通过定义结构应该有最小的(如果有的话)性能差异。它更多的是为了编码方便而不是性能。
作为一个实用主义者,我会说继续使用元组 直到你有一个可衡量的问题。
The search result should be immutable
这是我看到的唯一让我考虑定义一个 readonly
结构的东西,因为 ValueTuple
默认情况下不是不可变的。
Because a struct is a [value type], not a reference type, I also wonder if BlockIndex.Block
(which is a class) will be a reference to the instance of block or a copy of the found block.
它仍然是一个参考。引用类型不会仅仅因为它们是结构的 属性 而不再是引用类型。引用的 value 将与结构一起携带,就像整数一样。
简介
到目前为止,我正在尝试围绕结构进行思考。我在“何时使用结构”这一主题上找到了很多答案。他们中的大多数都含糊不清,例如一般情况下反对使用结构的建议,只有少数例外。有关于何时使用结构的解释(几个例子):
- 不可变数据
- 与引用语义相反的值语义
- 在传递结构化数据的代码中需要它们 to/from C/C++
- 除非需要,否则不要使用结构
但是没有示例代码说明这种情况实际发生的时间是有意义的。
最有名的 Questions/Answers 可能是这个: When should I use a struct rather than a class in C#?
项目结构
class StorageBlock<Type>
:
/// this is a storage block. It is not a struct because the data is not immutable and it
/// should be passed by reference
public class StorageBlock<Type>
{
Type[] Data;
/* other stuff */
}
方法BlockSearcher()
:
public (StorageBlock<Type> FoundBlock, int FoundIndex) SearchBlock(Type searchForThisElement)
{
StorageBlock<Type> found = Blocks.Find(searchForThisElement);
int index = Array.IndexOf(found.Data, searchForThisElement);
return (found,index);
}
来电者示例:
(StorageBlock<Type> FoundBlock, int FoundIndex) searchResult = SearchBlock(searchElement);
/* process SearchResult(s) */
问题
我想知道将 (StorageBlock<Type> FoundBlock, int FoundIndex) searchResult
转换为结构是否有意义。搜索结果应该是不可变的。它只是为了提供来自特定索引操作的 return。
像这样:
struct BlockIndex
{
StorageBlock<Type> Block;
int Index;
}
因为结构是数据类型,而不是引用类型,我还想知道 BlockIndex.Block
(这是一个 class)是否会引用块的实例或找到方块。
您似乎是在将结构与元组(编译为 ValueTuple
,而不是 Tuple
)进行比较,而不是将结构与 类(这是更常见的问题和原始建议的上下文)。使用该语法定义元组是 C# 中较新的构造,因此我不知道是否有关于是显式定义结构还是使用元组的最佳实践。
Behind-the-scenes,元组被实现为 ValueTuple
结构,因此通过定义结构应该有最小的(如果有的话)性能差异。它更多的是为了编码方便而不是性能。
作为一个实用主义者,我会说继续使用元组 直到你有一个可衡量的问题。
The search result should be immutable
这是我看到的唯一让我考虑定义一个 readonly
结构的东西,因为 ValueTuple
默认情况下不是不可变的。
Because a struct is a [value type], not a reference type, I also wonder if
BlockIndex.Block
(which is a class) will be a reference to the instance of block or a copy of the found block.
它仍然是一个参考。引用类型不会仅仅因为它们是结构的 属性 而不再是引用类型。引用的 value 将与结构一起携带,就像整数一样。