在Tuples之前,我曾经创建一个class
及其变量,然后从这个类创建对象,并使该对象成为某些函数的返回类型.
现在用的元组,我可以做同样的在C#7.0,我们可以将元组性质可以理解的名称(这是之前item1
,item2
等..)
所以现在我想知道,我应该何时使用元组,何时应该在c#7.0中创建一个类?
这在 C# 7.3 (Framework 4.8) 中正确编译:
(string, string) s = ("a", "b");
(object, string) o = s;
Run Code Online (Sandbox Code Playgroud)
我知道这是以下内容的语法糖,它也可以正确编译:
ValueTuple<string, string> s = new ValueTuple<string, string>("a", "b");
ValueTuple<object, string> o = s;
Run Code Online (Sandbox Code Playgroud)
所以,看起来 ValueTuples 可以被协变分配,这太棒了!
不幸的是,我不明白为什么:我的印象是 C#只支持接口和委托的协变。ValueType
都不是。
事实上,当我尝试用我自己的代码复制这个功能时,我失败了:
struct MyValueTuple<A, B>
{
public A Item1;
public B Item2;
public MyValueTuple(A item1, B item2)
{
Item1 = item1;
Item2 = item2;
}
}
...
MyValueTuple<string, string> s = new MyValueTuple<string, string>("a", "b"); …
Run Code Online (Sandbox Code Playgroud) 是否可以在C#7中创建ValueTuple列表?
像这样:
List<(int example, string descrpt)> Method()
{
return Something;
}
Run Code Online (Sandbox Code Playgroud) 如何检查System.ValueTuple是否为默认值?粗略的例子:
(string foo, string bar) MyMethod() => default;
// Later
var result = MyMethod();
if (result is default){ } // doesnt work
Run Code Online (Sandbox Code Playgroud)
我可以MyMethod
使用default
C#7.2的语法返回默认值.我无法检查默认情况?这些是我试过的:
result is default
result == default
result is default(string, string)
result == default(string, string)
Run Code Online (Sandbox Code Playgroud) 在尝试将命名值元组序列化为JSON字符串时,它会丢失分配给项目的名称
(string type, string text) myTypes = ("A", "I am an animal");
var cnvValue = JsonConvert.SerializeObject(myTypes);
Run Code Online (Sandbox Code Playgroud)
我期待序列化值为
{"type":"A","text":"我是动物"}
但实际结果是
{"Item1":"A","Item2":"我是动物"}
我有兴趣知道两件事
我正在尝试检查object
变量是否是(int, int)
,如果可以,我将使用强制类型转换的变量,因此我尝试了以下代码:
//this one gives the error
public void MyMethodWithIs(object val)
{
if(val is (int id, int name) pair)
{
ConsoleWriteLine($"{pair.id}, {pair.name}");
}
}
//This one works
public void MyMethodWithAs(object val)
{
var pair = val as (int id, int name)?;
if(pair!=null)
{
ConsoleWriteLine($"{pair.id}, {pair.name}");
}
}
Run Code Online (Sandbox Code Playgroud)
该MyMethodWithIs
方法在编辑器中给出以下错误:
找不到适用于类型的合适的解构实例或扩展方法
我的问题
为什么一个工作正常,而另一个却出现错误呢?我认为它MyMethodWithIs
更具可读性,适合用于我的案子,但由于出现错误,我无法使用它。
如果我有一个viewmodel属性
public (string Mdf, string MdfPath) MachineDefinition { get; set; }
Run Code Online (Sandbox Code Playgroud)
我尝试在XAML/WPF中绑定它
<Label Content="{Binding Path=MachineDefinition.Item2}" />
Run Code Online (Sandbox Code Playgroud)
要么
<Label Content="{Binding Path=MachineDefinition.MdfPath}" />
Run Code Online (Sandbox Code Playgroud)
我犯了同样的错误
我看到ValueTuple字段实际上是字段而不是属性.这是问题吗?
C#7.0(在VS 2017中)的新功能是否可以将元组字段名称转换为KeyValuePairs?
让我们假设我有这个:
class Entry
{
public string SomeProperty { get; set; }
}
var allEntries = new Dictionary<int, List<Entry>>();
// adding some keys with some lists of Entry
Run Code Online (Sandbox Code Playgroud)
做一些像这样的事情会很好:
foreach ((int collectionId, List<Entry> entries) in allEntries)
Run Code Online (Sandbox Code Playgroud)
我已经添加System.ValueTuple
到项目中了.
能够像这样写它会比这种传统风格好得多:
foreach (var kvp in allEntries)
{
int collectionId = kvp.Key;
List<Entry> entries = kvp.Value;
}
Run Code Online (Sandbox Code Playgroud) 由于C#7引入了值元组,是否有一个有意义的场景,它们比元组更适合?
例如,以下行
collection.Select((x, i) => (x, i)).Where(y => arr[y.i].f(y.x)).ToArray();
Run Code Online (Sandbox Code Playgroud)
制作以下内容
collection.Select((x, i) => new {x, i}).Where(y => arr[y.i].f(y.x)).ToArray();
Run Code Online (Sandbox Code Playgroud)
多余的.
什么是一个用于更好地使用另一个的用例(出于性能原因或优化)?
显然,如果需要超过六个字段,则不能使用元组,但它是否有一些细微之处呢?
我有一个用例,我需要检查一个值是否是C#7 ValueTuple,如果是,则循环遍历每个项目.我试着用检查obj is ValueTuple
和obj is (object, object)
但是这两个的返回false.我发现我可以使用obj.GetType().Name
并检查它是否以它开头,"ValueTuple"
但这对我来说似乎很蹩脚.任何替代品都会受到欢迎.
我也有获得每个项目的问题.我尝试Item1
使用此处找到的解决方案:如何检查c#中动态匿名类型上是否存在属性?但((dynamic)obj).GetType().GetProperty("Item1")
返回null.我希望我能做一件事while
来获得每件物品.但这不起作用.我如何获得每件商品?
更新 - 更多代码
if (item is ValueTuple) //this does not work, but I can do a GetType and check the name
{
object tupleValue;
int nth = 1;
while ((tupleValue = ((dynamic)item).GetType().GetProperty($"Item{nth}")) != null && //this does not work
nth <= 8)
{
nth++;
//Do stuff
}
}
Run Code Online (Sandbox Code Playgroud) c# ×10
valuetuple ×10
c#-7.0 ×4
tuples ×2
.net ×1
c#-7.2 ×1
covariance ×1
dictionary ×1
json.net ×1
wpf ×1
xaml ×1