ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 从字典中获取值而不进行拆箱?

2019-06-06 19:55:06  阅读:226  来源: 互联网

标签:c casting boxing generics


我想知道是否可以运行以下代码但没有取消装箱行: –

t.Value = (T)x;

或者,如果有另一种方法可以做这种操作?

这是完整的代码: –

public class ValueWrapper<T>
{
    public T Value { get; set; }
    public bool HasValue { get; set; }

    public ValueWrapper()
    {
        HasValue = false;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Dictionary<string, object> myDictionary = new Dictionary<string, object>();

        myDictionary.Add("key1", 6);
        myDictionary.Add("key2", "a string");

        var x2 = GetValue<int>(myDictionary, "key1");
        if (x2.HasValue)
            Console.WriteLine("'{0}' = {1}", "key1", x2.Value);
        else
            Console.WriteLine("No value found");

        Console.ReadLine();
    }

    static ValueWrapper<T> GetValue<T>(IDictionary<string, object> dictionary, string key)
    {
        ValueWrapper<T> t = new ValueWrapper<T>();

        object x = null;
        if (dictionary.TryGetValue(key, out x))
        {
            if (x.GetType() == typeof(T))
            {
                t.Value = (T)x;
                t.HasValue = true;
            }
        }

        return t;
    }
}

提前致谢!!

理查德.

解决方法:

一些评论:

> t.Value =(T)x;

演员是必要的.这是因为t.Value属于T类型,x属于object类型. C#的强类型性质要求你告诉编译器“看,我知道这可能不安全,但你可以尝试为我做这件事,无论是通过转换或拆箱还是其他什么?谢谢!”

2.

object x = null;
if (dictionary.TryGetValue(key, out x)) {
    if (x.GetType() == typeof(T)) {
        t.Value = (T)x;
        t.HasValue = true;
    }
}

return t;

如果x是从T派生的类的实例,该怎么办?或者,如果x是实现接口的类的实例而T是该接口?现在,您将返回ValueWrapper< T>的实例.这表示字典中没有带密钥的对象.我认为这与大多数人的期望非常违反直觉.

另外,如果你不打算在词典中没有包含与键键匹配的值时,我认为你应该将你的方法重命名为TryGetValue,接受一个类型为ValueWrapper< T>的out参数,并返回一个表示成功的bool /失败.

3.

回应您的评论,这是一个解决方案.

public interface IValueWrapper {
    object Value { get; set; }
    bool HasValue { get; set; }
}

public class ValueWrapper<T> : IValueWrapper {
    public T Value { get; set; }
    object IValueWrapper.Value { 
        get { return Value; }
        set { this.Value = (T)value; }
    }
    public bool HasValue { get; set; }

    public ValueWrapper() {
        this.HasValue = false;
    }

    public ValueWrapper(T value) {
        this.Value = value;
        this.HasValue = value != null;
    }
}

public static class DictionaryExtensions {
    public static void Add<T>(
        this IDictionary<string, IValueWrapper> dictionary,
        string key,
        T value
    ) {
        ValueWrapper<T> valueWrapper = new ValueWrapper<T>(value);
        dictionary.Add(key, valueWrapper);
    }

    public static bool TryGetWrappedValue<T>(
        IDictionary<string, IValueWrapper> dictionary,
        string key,
        out ValueWrapper<T> value
    ) {
        IValueWrapper valueWrapper;
        if (dictionary.TryGetValue(key, out valueWrapper)) {
            value = (ValueWrapper<T>)valueWrapper;
            return true;
        }
        else {
            value = null;
            return false;
        }
    }
}

用法:

var dict = new Dictionary<string, IValueWrapper>();
dict.Add("hello", 5);
ValueWrapper<int> value;
dict.TryGetWrappedValue("hello", out value);

你必须添加参数检查等.

标签:c,casting,boxing,generics
来源: https://codeday.me/bug/20190606/1189595.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有