如何用C#中的特定键更新字典值 [英] How to update value of dictionary with specific key in C#

查看:73
本文介绍了如何用C#中的特定键更新字典值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法在现有字典中添加新值,使用它的关键参数进行检查?

解决方案

请参阅我们与SaschaLefévre在评论中的建设性讨论解决方案1.它还不是很全面,因为用户无法访问按密钥修改的所有变体。此外,异常信息不提供信息。重要的是要记住键和值类型可能不能很好地表现为字符串。



因为我是建议大多数改进的人,但它不是总之,让我总结一下更通用的解决方案:

 使用 System.Collections.Generic; 

public class DictionaryWrapper< KEY,VALUE> {

public enum ValueModificationResult {
成功,
KeyNotFound,
NoValueChangeNeeded,
}

字典< KEY,VALUE> dictionary = new 字典< KEY,VALUE>();

public ValueModificationResult ModifyExceptionless(KEY key,VALUE value ){
VALUE oldValue;
if (dictionary.TryGetValue(key, out oldValue)){
< span class =code-keyword> if ( value .Equals(oldValue))
返回 ValueModificationResult.NoValueChangeNeeded;
dictionary [key] = value ;
return ValueModificationResult.Success;
} else
return ValueModificationResult.KeyNotFound;
} // ModifyExceptionless

// variant:
public bool ModifyCombined(KEY键,VALUE value ){
VALUE oldValue;
if (dictionary.TryGetValue(key, out oldValue)){
< span class =code-keyword> bool result =!value.Equals(oldValue);
if (result)
dictionary [key] = value ;
返回结果;
} else
throw new ValueModificationException< KEY,VALUE>(键,);
} // ModifyCombined

public ValueModificationResult AddOrModify(KEY key,VALUE value ){
var result = ModifyExceptionless(key, value );
if (result == ValueModificationResult.KeyNotFound){
dictionary.Add(key, value < /跨度>);
return ValueModificationResult.Success;
} // 如果
返回结果;
} // AddOrModif

// 这隐含地暴露了字典功能的其余部分:
public static 隐式 operator 字典< KEY ,VALUE>(DictionaryWrapper< KEY,VALUE>包装器)
{ return wrapper.dictionary; }

// 或者或另外,包装一些字典功能
// ...

} // class DictionaryWrapper





  public   class  ValueModificationException< KEY,VALUE> :System.ApplicationException {
internal ValueModificationException(KEY key,VALUE value ){
.Key = key; this .Value = value ;
} // ValueModificationException
公开 KEY Key { get ; private set ; }
public VALUE值{ get ; private set ; }
} // class ValueModificationException





用法:

<前lang =c#> UsageSample {

static void Test(){
DictionaryWrapper< string,int> wrapper = new DictionaryWrapper< string,int>();
Dictionary< string,int> dictionary = wrapper;
dictionary.Add( 1 1 );
var result = wrapper.AddOrModify( 1 2 ); // 成功
/// ...
} // 测试

} // class UsageSample





注意使用异常属性的私有setter(从外部类只读)和 internal 构造函数(尽量不要提供更多访问权限)。另请注意 Modify 方法的 ModifyExceptionless 变体的一些好处:它更适合在<$ c $中使用c> AddOrModify 。



-SA


当然:

  //  无论someKey如何,这都有效以前是否存在于词典中: 
yourDictionary [someKey] = newValue;


// 如果你想确保someKey实际上已经是现在:
if (yourDictionary.Contains(someKey))
yourDictionary [someKey] = newValue;
else
// throw例外情况


// 如果你想确保someKey尚未出现:
yourDictionary.Add(someKey,newValue);
// (否则会抛出异常)





编辑:



您可以为第二种情况创建扩展方法上面:

 使用系统; 
使用 System.Collections.Generic;

命名空间 MyExtensionClasses
{
public static class MyDictionaryExtension
{
// 将添加或更新
// 如果添加或更新了键值对,则返回true
// return如果新值等于现有值,则为false
public static bool AddOrUpdate< TKey,TValue>(字典< TKey,TValue> dict,TKey键,TValue < span class =code-sdkkeyword> value )
{
bool addedOrUpdat ed = false ;
TValue oldValue;
if (!dict.TryGetValue(key, out oldValue)||!value.Equals (oldValue))
{
dict [key] = value ;
addedOrUpdated = true ;
}
return addedOrUpdated;
}

// 只会在密钥已存在的情况下更新值
// 并抛出异常
public static void UpdateExisting< TKey,TValue>(字典< TKey,TValue>字典,TKey键,TValue
{
if (dict.ContainsKey(key))
dict [key] = value ;
else
throw new InvalidOperationException( 无法更新,因为在字典中找不到密钥: + key.ToString ());
}
}
}



您只需将上面的代码复制到新的代码文件中,插入使用MyExtensionClasses; 在您要使用它的代码文件的顶部,然后使用这些方法,就像它们是Dictionary类的常规方法一样。


< blockquote>

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

//检查词典中是否存在Key
if(!dictionary.ContainsKey(Key))
{
dictionary [Key ] =价值;

}


Is there any way to add new value into existing dictionary, using it's key parameter for check up?

解决方案

Please see our constructive discussion with Sascha Lefévre in comments to Solution 1. It is not yet quite comprehensive, as not all variants of modification by key are accessible to the user. Also, exception information is not informative. It is important to remember that key and value types may be not well presentable as strings.

As I was the one who suggested most of improvements, but it wasn't enough, let me summarize it on more general solution:

using System.Collections.Generic;

public class DictionaryWrapper<KEY, VALUE> {

    public enum ValueModificationResult {
        Success,
        KeyNotFound,
        NoValueChangeNeeded,
    }

    Dictionary<KEY, VALUE> dictionary = new Dictionary<KEY, VALUE>();

    public ValueModificationResult ModifyExceptionless(KEY key, VALUE value) {
        VALUE oldValue;
        if (dictionary.TryGetValue(key, out oldValue)) {
            if (value.Equals(oldValue))
                return ValueModificationResult.NoValueChangeNeeded;
            dictionary[key] = value;
            return ValueModificationResult.Success;
        } else
            return ValueModificationResult.KeyNotFound;
    } //ModifyExceptionless

    // variant:
    public bool ModifyCombined(KEY key, VALUE value) {
        VALUE oldValue;
        if (dictionary.TryGetValue(key, out oldValue)) {
            bool result = !value.Equals(oldValue);
            if (result)
                dictionary[key] = value;
            return result;
        } else
            throw new ValueModificationException<KEY, VALUE>(key, value);
    } //ModifyCombined

    public ValueModificationResult AddOrModify(KEY key, VALUE value) {
        var result = ModifyExceptionless(key, value);
        if (result == ValueModificationResult.KeyNotFound) {
            dictionary.Add(key, value);
            return ValueModificationResult.Success;
        } //if
        return result;
    } //AddOrModif

    // this implicitely exposes the rest of Dictionary functionality:
    public static implicit operator Dictionary<KEY, VALUE>(DictionaryWrapper<KEY, VALUE> wrapper)
       { return wrapper.dictionary; }

    // alternatively or additionally, wrap some Dictionary functionality
    // ...

} //class DictionaryWrapper



public class ValueModificationException<KEY, VALUE> : System.ApplicationException {
    internal ValueModificationException(KEY key, VALUE value) {
        this.Key = key; this.Value = value;
    } //ValueModificationException
    public KEY Key { get; private set; }
    public VALUE Value { get; private set; }
} //class ValueModificationException



Usage:

class UsageSample {

    static void Test() {
        DictionaryWrapper<string, int> wrapper = new DictionaryWrapper<string,int>();
        Dictionary<string, int> dictionary = wrapper;
        dictionary.Add("1", 1);
        var result = wrapper.AddOrModify("1", 2); //Success
        ///...
    } //Test

} //class UsageSample



Note the use of private setters of exception properties (read-only from outside class) and internal constructor (try not to give more access then required). Also note some benefits of the ModifyExceptionless variant of the Modify method: it is more suitable for use in AddOrModify.

—SA


Of course:

// this will work regardless if "someKey" was previously present in the dictionary or not:
yourDictionary[someKey] = newValue;


// if you want to ensure that "someKey" actually is already present:
if (yourDictionary.Contains(someKey))
   yourDictionary[someKey] = newValue;
else
   // throw an Exception or something


// if you want to ensure that "someKey" is NOT already present:
yourDictionary.Add(someKey, newValue);
// (will throw an Exception otherwise)



Edit:

You could create an extension method for the "second case" above:

using System;
using System.Collections.Generic;

namespace MyExtensionClasses
{
  public static class MyDictionaryExtension
  {
    // will add or update
    // returns true if the key-value-pair was added or updated
    // return false if the new value was equal to the already existing value
    public static bool AddOrUpdate<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue value)
    {
        bool addedOrUpdated = false;
        TValue oldValue;
        if (!dict.TryGetValue(key, out oldValue) || !value.Equals(oldValue))
        {
            dict[key] = value;
            addedOrUpdated = true;
        }
        return addedOrUpdated;
    }

    // will only update a value if the key already exists
    // and throw an exception otherwise
    public static void UpdateExisting<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue value)
    {
        if (dict.ContainsKey(key))
            dict[key] = value;
        else
            throw new InvalidOperationException("Can't update because key not found in dictionary: " + key.ToString());
    }
  }
}


You can just copy the code above into a new code file, insert a using MyExtensionClasses; at the top of your code files where you want to use it and then use the methods as if they were regular methods of the Dictionary-class.


Dictionary<string, string> dictionary = new Dictionary<string, string>();
            
//Check if "Key" is already present in dictionary
if (!dictionary.ContainsKey("Key"))
            {
                dictionary["Key"] = "Value" ;

            }


这篇关于如何用C#中的特定键更新字典值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆