遍历异构且类型安全的字典

遍历异构且类型安全的字典

本文介绍了遍历异构且类型安全的字典的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个类似字典,但是数据类型( TValue )从一个键更改为另一个键.

I need a container that works like a ditionary but where the type of data (TValue) change from one key to the other.

我还需要迭代它.

推荐答案

用于异构且类型安全的字典部分

Wilka的响应是一个好的开始.

诀窍是将类型键入密钥.

The trick is to put the type in the key.

/// <summary>
/// Base class for all dictionary key.
///
/// <remarks>The key name is REALLY usefull for debug purpose.</remarks>
/// </summary>
abstract class HeterogeneousDictionaryKeyBase
{
    readonly string _name;

    protected HeterogeneousDictionaryKeyBase(string name)
    {
        _name = name;
    }

    public override string ToString()
    {
        return _name;
    }
}

sealed class HeterogeneousDictionaryKey<TValue> : HeterogeneousDictionaryKeyBase
{
    public HeterogeneousDictionaryKey(string name)
        : base(name)
    {
    }
}

因此对字典的调用将具有通用值类型:

So calls to dictionary will have a generic value type:

/// <summary>
/// <remarks>The [] operator can not be generic, so we implement it has a getter and a setter</remarks>
/// </summary>
class HeterogeneousDictionary
{
    private readonly Dictionary<HeterogeneousDictionaryKeyBase, object> _dictionary = new Dictionary<HeterogeneousDictionaryKeyBase, object>();

    public void Add<TValue>(HeterogeneousDictionaryKey<TValue> key, TValue value)
    {
        _dictionary.Add(key, value);
    }

    public TValue Get<TValue>(HeterogeneousDictionaryKey<TValue> key)
    {
        return (TValue)_dictionary[key];
    }

    public void Set<TValue>(HeterogeneousDictionaryKey<TValue> key, TValue value)
    {
        _dictionary[key] = value;
    }

    public bool TryGetValue<TValue>(HeterogeneousDictionaryKey<TValue> key, out TValue value)
    {
        object result;
        if (_dictionary.TryGetValue(key, out result) && result is TValue)
        {
            value = (TValue)result;
            return true;
        }

        value = default(TValue);
        return false;
    }
}

用法很简单:

var dictionary = new HeterogeneousDictionary();

var keyName = new HeterogeneousDictionaryKey<string>("keyName");
var keyAge = new HeterogeneousDictionaryKey<int>("keyAge");

dictionary.Set(keyName, "Orace");
dictionary.Set(keyAge, 8);

...

var name = dictionary.Get(keyName);
var age = dictionary.Get(keyAge);

对于迭代部分

针对字典键的访客模式可以解决问题.

A visitor pattern against the dictionary keys will do the trick.

首先访问者界面:

interface IHeterogeneousDictionaryKeyVisitor
{
    void Visit<TValue>(HeterogeneousDictionaryKey<TValue> key);
}

然后我们使 HeterogeneousDictionaryKey 可以配合使用:

Then we made the HeterogeneousDictionaryKey cooperate:

abstract class HeterogeneousDictionaryKeyBase
{
    ...

    public abstract void Accept(IHeterogeneousDictionaryKeyVisitor visitor);

    ...
}

sealed class HeterogeneousDictionaryKey<TValue> : HeterogeneousDictionaryKeyBase
{
    ...

    public override void Accept(IHeterogeneousDictionaryKeyVisitor visitor)
    {
        visitor.Visit(this);
    }
}

现在,我们可以公开 HeterogeneousDictionary 键:

Now we can expose the HeterogeneousDictionary keys:

class HeterogeneousDictionary
{
    ...

    public Dictionary<HeterogeneousDictionaryKeyBase, object>.KeyCollection Keys
    {
        get { return _dictionary.Keys; }
    }

    ...
}

这一切.

这里是将字典安全地复制到另一个字典的用法示例

Here an example of usage to safely copy a dictionary to an other

class DictionaryCopier : IHeterogeneousDictionaryKeyVisitor
{
    readonly HeterogeneousDictionary _source;
    readonly HeterogeneousDictionary _destination;

    public DictionaryCopier(HeterogeneousDictionary source, HeterogeneousDictionary destination)
    {
        _source = source;
        _destination = destination;
    }

    public void PerformCopy()
    {
        foreach (var key in _source.Keys)
        {
            // See you soon.
            key.Accept(this);
        }
    }

    /// <summary>
    /// We fall back here with a typed key.
    /// </summary>
    public void Visit<TValue>(HeterogeneousDictionaryKey<TValue> key)
    {
        // Here the value is typed.
        var value = _source.Get(key);

        _destination.Add(key, value);
    }
}

这篇关于遍历异构且类型安全的字典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 22:45