我玩弄了ValueTuple
结构并试图实现一个不可变的复合键.密钥由值类型组成.
我尝试用一些单元测试打破以下实现,到目前为止还没有成功.我错过了什么吗?
这也只是出于好奇,我想ValueTuple
在.NET 4.7发布之前得到s和它的局限性.
到目前为止,我对a的理解ValueTuple
是它只作为变量而不是作为字段或属性变化.不知道"可变"在这里意味着什么.更改ValueTuple
实例实际上是否创建了一个新的ValueTuple
(就像它的常识一样,字符串是"不可变的"但实际上是引用类型)?
从这个答案
System.ValueTuple
不仅是一个struct
,它是一个可变的,并且在使用它们时必须要小心.想想当一个班级System.ValueTuple
作为一个领域时会发生什么.
在这里我的实施和测试
public interface IHaveCompositeKey
{
(Guid id, string name) Key { get; }
}
public class ImmutableKey : IHaveCompositeKey
{
public (Guid id, string name) Key { get; }
public ImmutableKey((Guid id, string name) key) => Key = key;
public override int GetHashCode() => Key.GetHashCode();
public override bool Equals(object obj)
{ …
Run Code Online (Sandbox Code Playgroud) 我正在使用Visual Studion 2017版本15.5.2和C#版本7.2.要点:
Color c = default; // or: c = default(Color); no difference
Debug.Print($"{c.Equals(default(Color))}"); // true
Debug.Print($"{c.Equals(default)}"); // false WHY?!
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用ValueTuple:
(string s, int i) t = default;
Debug.Print($"{t.Equals(default((string, int)))}"); // true
Debug.Print($"{t.Equals(default)}"); // true
Run Code Online (Sandbox Code Playgroud)
它应该是这样的吗?
当我检查缓存以查看ValueTuple是否在缓存中时,我使用下面的代码。在这种情况下,返回的值将为空(高速缓存中不存在)。代码运行时object not set to instance of an object
,在第一行出现错误。是否有将对象强制转换为ValueTuple的正确方法?
var geo = ((double, double))CacheEngine.Get(key);
if (!geo.Equals(default(ValueTuple<double, double>))) return geo;
Run Code Online (Sandbox Code Playgroud) 我想使用ValueTuple的命名功能如下:
IEnumerable<(string, char, int)> valueTuples = new(string, char, int)[]
{
("First", '1', 1),
("Second", '2', 2),
("Third", '3', 3)
};
var projection1 = valueTuples.Select(((string s, char c, int i) tuple) => tuple.i);
Run Code Online (Sandbox Code Playgroud)
但它不会编译错误消息,这不是很有帮助.然而这些都编译:
var projection2 = valueTuples.Select(tuple => tuple.Item1);
var projection3 = valueTuples.Select(((string, char, int) tuple) => tuple.Item1);
Run Code Online (Sandbox Code Playgroud)
尝试更直接的方法,这不编译BUT提供更有帮助的错误消息:
var projection4 = Enumerable.Select(
valueTuples, ((string s, char c, int i) tuple) => tuple.i);
Run Code Online (Sandbox Code Playgroud)
这导致尝试这个,编译:
var projection5 = Enumerable.Select<(string, char, int), int>(
valueTuples, ((string s, char c, int i) tuple) => …
Run Code Online (Sandbox Code Playgroud) 我正在使用Web API。我有点懒,决定从控制器返回一个值元组。
[HttpGet]
[Route(AuthAPIRoutes.GET_MFA_DEVICES)]
public (string Type, string Value)[] GetMultiFactoryMethods()
{
return GlobalFactory<IPaystreamMFASecurityService>.Instance.GetMultiFactorMethods();
}
Run Code Online (Sandbox Code Playgroud)
JSON响应似乎没有使用适当的命名,这是否已被优化?
{
"item1": "Phone",
"item2": "1-512-555-0550"
}
Run Code Online (Sandbox Code Playgroud)
注意:我知道我可以明确创建一个模型来避免此问题。我想了解发生了什么,为什么响应中不尊重我的值元组名称?
我正在尝试反序列化为[{"foo": "1", "bar": false}, {"foo": "2", "bar": false}]
类型List<(string, bool)>
:
JsonConvert.DeserializeObject<List<(string foo, bool bar)>>(json)
Run Code Online (Sandbox Code Playgroud)
但始终会获得默认值列表 - (null, false)
。
如何实现正确的反序列化?
PS 我对用于此目的的任何模型/类都不感兴趣。我需要确切的值元组。
有很多问题只包含没有GCTuple(class)
压力的情况下与ValueTuple(struct)
All gone with之间的差异。但我不明白为什么要接受所有数据类型?为什么不只接受设计为结构的结构。ValueTuple
ValueTuple
ValueTuple
乍看上去。将引用类型与 ValueTuple 一起使用是否安全且性能更高?
例子
ValueTuple<CarClass, EngineClass> CarBody
或者我们应该去吗
Tuple<CarClass, EngineClass> CarBody
我看到的所有示例都包含ValueTuple<int, int, long, structs only>
它是否仅用于此目的?我使用的许多代码都使用ValueTuple<ReferenceTypes>
C# 7 ValueTuple 是否有类似于 Python 切片的功能?C# 中值元组的语法与 Python 类似,但我找不到一种优雅的方法来从元组获取子元组。
在Python 3中:
tuple = (1,2,3)
subtuple = t[:2] #subtuple is (1, 2)
Run Code Online (Sandbox Code Playgroud)
在 C#7 中:
var tuple = (1,2,3) //Very similar to Python!
var subtuple = (tuple.Item1, tuple.Item2) //Not very elegant, especially for bigger tuples
Run Code Online (Sandbox Code Playgroud) 我想从一组值动态创建一个值类型元组。
示例:我有一个给定的IEnumerable<T>
,我想根据该集合创建一个元组。
我怎样才能做到这一点?
似乎可以动态实现值类型元组内的访问,但没有任何迹象表明可以对值类型元组的创建进行相同的操作。
我的目的之一是利用本文中描述的此类元组的 Equality 和 HashCode 的属性
c# ×10
valuetuple ×10
.net ×2
c#-7.0 ×2
.net-core ×1
c#-7.2 ×1
default ×1
ienumerable ×1
immutability ×1
json ×1
json.net ×1
mutability ×1
out ×1
python ×1
tuples ×1