Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何调用字典<;K、 V>;。TryGetValue(),其中K:谓词<;T>;,V:枚举_C#_Linq_Dictionary_Predicate_Trygetvalue - Fatal编程技术网

C# 如何调用字典<;K、 V>;。TryGetValue(),其中K:谓词<;T>;,V:枚举

C# 如何调用字典<;K、 V>;。TryGetValue(),其中K:谓词<;T>;,V:枚举,c#,linq,dictionary,predicate,trygetvalue,C#,Linq,Dictionary,Predicate,Trygetvalue,我有字典: 接收 SomeStruct.Bar 但是TryGetValue()的第一个参数是谓词,而不仅仅是T。我怎么能做我想做的 我发现只有一个肮脏的解决办法: var kpv = dic.FirstOrDefault(p => p.Key(99)); if (kpv.Key != null) var result = kpv.Value; 还有其他方法吗 或者如何正确实现我的想法?-将键声明为段而不是常量。如果谓词列表不太长,您可以将它们添加到列表中,然后执行LINQ查询:

我有
字典

接收

SomeStruct.Bar
但是
TryGetValue()
的第一个参数是
谓词
,而不仅仅是
T
。我怎么能做我想做的

我发现只有一个肮脏的解决办法:

var kpv = dic.FirstOrDefault(p => p.Key(99));
if (kpv.Key != null)
    var result = kpv.Value;
还有其他方法吗


或者如何正确实现我的想法?-将键声明为段而不是常量。

如果谓词列表不太长,您可以将它们添加到
列表中,然后执行LINQ查询:

var lt10 = new KeyValuePair<Predicate<Double>, SomeStruct>(d => d < 10, SomeStruct.Foo);
var gt90 = new KeyValuePair<Predicate<Double>, SomeStruct>(d => d > 90, SomeStruct.Bar);
var predicates = new List<KeyValuePair<Predicate<Double>, SomeStruct>>() { lt10, gt90 };

var result = predicates.FirstOrDefault(p => p.Key(99));
var lt10=newkeyvaluepair(d=>d<10,SomeStruct.Foo);
var gt90=新的KeyValuePair(d=>d>90,SomeStruct.Bar);
var谓词=new List(){lt10,gt90};
var result=predicates.FirstOrDefault(p=>p.Key(99));
最好使用
SomeStruct?
而不是
SomeStruct
,此外,从那时起,如果与任何一个不匹配,那么
FirstOrDefault
将给出一个明确的结果


如果你的列表很长,你会想考虑某种数据结构,允许在一个范围内查询,比如.

如果谓词列表不太长,你可以把它们添加到<代码>列表中,然后执行LINQ查询:

var lt10 = new KeyValuePair<Predicate<Double>, SomeStruct>(d => d < 10, SomeStruct.Foo);
var gt90 = new KeyValuePair<Predicate<Double>, SomeStruct>(d => d > 90, SomeStruct.Bar);
var predicates = new List<KeyValuePair<Predicate<Double>, SomeStruct>>() { lt10, gt90 };

var result = predicates.FirstOrDefault(p => p.Key(99));
var lt10=newkeyvaluepair(d=>d<10,SomeStruct.Foo);
var gt90=新的KeyValuePair(d=>d>90,SomeStruct.Bar);
var谓词=new List(){lt10,gt90};
var result=predicates.FirstOrDefault(p=>p.Key(99));
最好使用
SomeStruct?
而不是
SomeStruct
,此外,从那时起,如果与任何一个不匹配,那么
FirstOrDefault
将给出一个明确的结果


如果你的列表很长,你会想考虑某种数据结构,它允许在一个范围内查询,比如.

,你必须循环你的标准,并运行每个谓词来对抗输入,看看它是否匹配。我看不出有任何理由在这里使用字典。

您必须循环检查您的条件,并针对输入运行每个谓词,以查看它是否匹配。我看不出有任何理由在这里使用字典。

使用字典无法做到这一点,因为它依赖于哈希值来快速确定在何处查找特定键

正如您所发现的,您可以直接调用谓词,但这需要调用O(n)个函数,这并不比使用一个列表,甚至一个大的if/then/else语句好多少

如果您的潜在谓词集合太长,无法作为选项,则需要创建自己的数据结构以满足您的目的。如果您只计划基于整数范围定义值,这应该不难,但如果谓词变得更复杂,它可能会失控

另一方面,F#语言,它内置了对这种定义的支持,使用。我不知道它是如何编译分支的,但我认为它相当聪明

编辑

下面是一个在F#中使用匹配表达式的示例,类似于:

dic.TryGetValue(99)
// Define the "choose" function
let choose value = 
    match value with
    | v when v < 10 -> 1
    | v when v > 90 -> 2
    | _ -> 0

// Test the "choose" function
let choice1 = choose 5
let choice2 = choose 15
let choice3 = choose 95
...
List<MySegment> list = new List<MySegment>();
...
list.Add(new MySegment { Predicate = d => d < 10, Result = SomeStruct.Foo });
list.Add(new MySegment { Predicate = d => d > 90, Result = SomeStruct.Bar });

...

public IEnumerable<SomeStruct> GetResults(double input)
{ 
    foreach (var item in list)
        if (item.Predicate(input))
             yield return item.Result;
}

我以前从未实际使用过F#,因此您必须四处寻找如何在C#程序中使用F#中的函数。

这不能使用字典来完成,因为它依赖于哈希值来快速确定在何处查找特定键

正如您所发现的,您可以直接调用谓词,但这需要调用O(n)个函数,这并不比使用一个列表,甚至一个大的if/then/else语句好多少

如果您的潜在谓词集合太长,无法作为选项,则需要创建自己的数据结构以满足您的目的。如果您只计划基于整数范围定义值,这应该不难,但如果谓词变得更复杂,它可能会失控

另一方面,F#语言,它内置了对这种定义的支持,使用。我不知道它是如何编译分支的,但我认为它相当聪明

编辑

下面是一个在F#中使用匹配表达式的示例,类似于:

dic.TryGetValue(99)
// Define the "choose" function
let choose value = 
    match value with
    | v when v < 10 -> 1
    | v when v > 90 -> 2
    | _ -> 0

// Test the "choose" function
let choice1 = choose 5
let choice2 = choose 15
let choice3 = choose 95
...
List<MySegment> list = new List<MySegment>();
...
list.Add(new MySegment { Predicate = d => d < 10, Result = SomeStruct.Foo });
list.Add(new MySegment { Predicate = d => d > 90, Result = SomeStruct.Bar });

...

public IEnumerable<SomeStruct> GetResults(double input)
{ 
    foreach (var item in list)
        if (item.Predicate(input))
             yield return item.Result;
}

我以前从未实际使用过F,因此您必须四处看看如何在C程序中使用F中的函数。

这里有几个错误:

谓词
不适合用作
TKey
。字典的键应该是识别一个值,而不是计算一个值

使用lambdas也没有任何意义。因为它们是匿名的,所以你不能得到任何等价物,也不能使用字典

有关说明,请参见此代码示例:

Predicate<double> fn_1 = d => d == 34.0d;
Predicate<double> fn_2 = d => d == 34.0d;

// Note: There are not equal
if (fn_1 == fn_2)
    Console.WriteLine("These are Equal?");
要遍历一系列谓词,并找到匹配的谓词,如下所示:

dic.TryGetValue(99)
// Define the "choose" function
let choose value = 
    match value with
    | v when v < 10 -> 1
    | v when v > 90 -> 2
    | _ -> 0

// Test the "choose" function
let choice1 = choose 5
let choice2 = choose 15
let choice3 = choose 95
...
List<MySegment> list = new List<MySegment>();
...
list.Add(new MySegment { Predicate = d => d < 10, Result = SomeStruct.Foo });
list.Add(new MySegment { Predicate = d => d > 90, Result = SomeStruct.Bar });

...

public IEnumerable<SomeStruct> GetResults(double input)
{ 
    foreach (var item in list)
        if (item.Predicate(input))
             yield return item.Result;
}
。。。
列表=新列表();
...
Add(newmysegment{Predicate=d=>d<10,Result=SomeStruct.Foo});
Add(newmysegment{Predicate=d=>d>90,Result=SomeStruct.Bar});
...
公共IEnumerable GetResults(双输入)
{ 
foreach(列表中的变量项)
if(项谓词(输入))
收益返回项。结果;
}

这里有两件事不对:

谓词
不适合用作
TKey
。字典的键应该是识别一个值,而不是计算一个值

使用lambdas也没有任何意义。因为它们是匿名的,所以你不能得到任何等价物,也不能使用字典

有关说明,请参见此代码示例:

Predicate<double> fn_1 = d => d == 34.0d;
Predicate<double> fn_2 = d => d == 34.0d;

// Note: There are not equal
if (fn_1 == fn_2)
    Console.WriteLine("These are Equal?");
要遍历一系列谓词,并找到匹配的谓词,如下所示:

dic.TryGetValue(99)
// Define the "choose" function
let choose value = 
    match value with
    | v when v < 10 -> 1
    | v when v > 90 -> 2
    | _ -> 0

// Test the "choose" function
let choice1 = choose 5
let choice2 = choose 15
let choice3 = choose 95
...
List<MySegment> list = new List<MySegment>();
...
list.Add(new MySegment { Predicate = d => d < 10, Result = SomeStruct.Foo });
list.Add(new MySegment { Predicate = d => d > 90, Result = SomeStruct.Bar });

...

public IEnumerable<SomeStruct> GetResults(double input)
{ 
    foreach (var item in list)
        if (item.Predicate(input))
             yield return item.Result;
}
。。。
列表=新列表();
...
Add(newmysegment{Predicate=d=>d<10,Result=SomeStruct.Foo});
Add(newmysegment{Predicate=d=>d>90,Result=SomeStruct.Bar});
...
公共IEnumerable GetResults(双输入)