Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.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# 通过使用if访问字典来缩短代码_C#_Dictionary_If Statement - Fatal编程技术网

C# 通过使用if访问字典来缩短代码

C# 通过使用if访问字典来缩短代码,c#,dictionary,if-statement,C#,Dictionary,If Statement,我有以下代码 Dictionary<string, string> changesDictionary = new Dictionary<string, string>(); if (changesDictionary.ContainsKey("field1")) { resultObject.field1 = changesDictionary["field1"]; } if (changesDictionary.ContainsKey("field2")) {

我有以下代码

Dictionary<string, string> changesDictionary = new Dictionary<string, string>();
if (changesDictionary.ContainsKey("field1"))
{
    resultObject.field1 = changesDictionary["field1"];
}
if (changesDictionary.ContainsKey("field2"))
{
    resultObject.field2 = changesDictionary["field2"];
}
if (changesDictionary.ContainsKey("field3"))
{
    resultObject.field3 = changesDictionary["field3"];
}

你可以一直这样做。一开始就比较冗长,但如果你有很多属性,那么它可能会有回报:

var fields = new (string key, Action<ResultObject, string> setter)[]
{
    ("field1", (x, val) => x.field1 = val),
    ("field2", (x, val) => x.field2 = val),
    ("field3", (x, val) => x.field3 = val),
};

foreach (var (key, setter) in fields)
{
    if (changesDictionary.TryGetValue(key, out var field))
    {
        setter(resultObject, field);
    }
}
公共静态类字典扩展
{
公共静态TValue GetOrDefault(此字典、TKey、TValue defaultValue)
{
if(dictionary.TryGetValue(键,输出值))
返回值;
返回默认值;
}
}
. . .
resultObject.field1=changesDictionary.GetOrDefault(“field1”,resultObject.field1);
resultObject.field2=changesDictionary.GetOrDefault(“field2”,resultObject.field2);
resultObject.field3=changesDictionary.GetOrDefault(“field3”,resultObject.field3);

如果您的对象有字段而不是属性,您可以使用TryGetValue来创建如下字段

changesDictionary.TryGetValue(nameof(ResultObject.field1), out resultObject.field1);
完整示例:

using System;
using System.Collections.Generic;

namespace ConsoleApp27
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var resultObject = new ResultObject();
            var changesDictionary = new Dictionary<string, string>();

            changesDictionary.Add(nameof(ResultObject.field1), "q1");
            changesDictionary.Add(nameof(ResultObject.field2), "q2");
            changesDictionary.Add(nameof(ResultObject.field3), "q3");
            changesDictionary.Add(nameof(ResultObject.field4), "q4");

            changesDictionary.TryGetValue(nameof(ResultObject.field1), out resultObject.field1);
            changesDictionary.TryGetValue(nameof(ResultObject.field2), out resultObject.field2);
            changesDictionary.TryGetValue(nameof(ResultObject.field3), out resultObject.field3);
            changesDictionary.TryGetValue(nameof(ResultObject.field4), out resultObject.field4);

            Console.WriteLine(resultObject.field1);
            Console.WriteLine(resultObject.field2);
            Console.WriteLine(resultObject.field3);
            Console.WriteLine(resultObject.field4);
            Console.ReadLine();
        }

        public class ResultObject
        {
            public string field1;
            public string field2;
            public string field3;
            public string field4;
        }
    }
}

使用本地函数:

void SetField(string fieldName, Action<string> updater)
{
    if (changesDictionary.TryGetValue(fieldName, out string fieldValue))
    {
        updater(fieldValue);
    }
}

SetField("field1", f => resultObject.field1 = f);
SetField("field2", f => resultObject.field2 = f);
SetField("field3", f => resultObject.field3 = f);
付出的代价=表现--

行计数=12而不是13,但如果您有20个字段要更新:

for (int i = 1; i <= 20; i++)
{
    SetField($"field{i}");
}
for(int i=1;i假设(给定
字段
字段的小写名称),
字段1
字段2
字段3
实际上是字段而不是属性,那么您可以编写一个局部函数来简化代码,如下所示:

Dictionary<string, string> changesDictionary = new Dictionary<string, string>();

void update(ref string field, string key)
{
    if (changesDictionary.TryGetValue(key, out var value))
        field = value;
}

update(ref resultObject.field1, "field1");
update(ref resultObject.field2, "field1");
update(ref resultObject.field3, "field1");
Dictionary changesDictionary=new Dictionary();
无效更新(参考字符串字段,字符串键)
{
if(更改离散的TryGetValue(键,输出var值))
字段=值;
}
更新(参考resultObject.field1,“field1”);
更新(参考resultObject.field2,“field1”);
更新(参考resultObject.field3,“field1”);

请注意,如果
字段1
等实际上是属性,则该选项将不起作用,因为您当然不能将
ref
与属性一起使用。

考虑使用
TryGetValue
而不是
ContainsKey
,以避免不必要的哈希查找。@mjwills这将使此代码稍微更详细,尽管您需要引入另一个保存中间值的变量。@DavidG C#现在有
out var
,因此没有@canton7仍然在创建另一个变量。
if(changesDictionary.TryGetValue(“field1”,out var field1)){resultObject.field1=field1;}
至少对我来说不是更详细吗?但也不是更详细……为什么需要
ResultObject
类型参数?@vc74,这样我就可以声明一个看起来像
(x,val)=>x.field1=val
的lambda,而不是
val=>ResultObject.field1=val
。它非常简洁(IMO),它允许编译器对多个
resultObject
实例重复使用同一个委托实例,这使它稍微便宜一点。但是您知道将要更新的是
resultObject
,不需要将其传递给操作。@vc74您是正确的,但请参阅我在上一篇评论中提出的两点。这是错误的。This将
resultObject.field1
设置为
null
if“field”没有出现在
changesDictionary
中。OP的代码保留其原始值。我也希望了解这里发生的情况,代码转储答案被认为是低质量的。我的意思是,是的,但为什么?这需要一点简单的代码,使其更复杂。不确定为什么每个人都将此复杂化:)@DavidG如果你更新了很多字段(而不仅仅是3个),那么这可能会使它更具可读性。是的,但看起来OP真的在更新3或4个字段,而且这些帖子都没有回答要缩短代码的问题。不,你不能这样简化。如果
changesDictionary
中不存在
key
,则它会将字段设置为
null
,而不是将其保留为当前值。是的,我刚刚意识到这无法简化,所以我删除了这些编辑。
q1
q2
q3
q4
void SetField(string fieldName, Action<string> updater)
{
    if (changesDictionary.TryGetValue(fieldName, out string fieldValue))
    {
        updater(fieldValue);
    }
}

SetField("field1", f => resultObject.field1 = f);
SetField("field2", f => resultObject.field2 = f);
SetField("field3", f => resultObject.field3 = f);
void SetField(string fieldName)
{
    if (changesDictionary.TryGetValue(fieldName, out string fieldValue))
    {
        PropertyInfo propertyInfo = resultObject.GetType().GetProperty(fieldName);
        propertyInfo.SetValue(resultObject, fieldValue);
    }
}

SetField("field1");
SetField("field2");
SetField("field3");
for (int i = 1; i <= 20; i++)
{
    SetField($"field{i}");
}
Dictionary<string, string> changesDictionary = new Dictionary<string, string>();

void update(ref string field, string key)
{
    if (changesDictionary.TryGetValue(key, out var value))
        field = value;
}

update(ref resultObject.field1, "field1");
update(ref resultObject.field2, "field1");
update(ref resultObject.field3, "field1");