从Dictionary获取值无需拆箱?
我想知道是否可以运行以下代码但没有拆箱行:-
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;
}
}
提前致谢!
理查德.
I was wondering if it's possible to run the following code but without the unboxing line:-
t.Value = (T)x;
Or maybe if there is another way to do this kind of operation?
Here is the full code:-
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;
}
}
Thanks in advance!!
Richard.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一些评论:
转换是必要的。这是因为
t.Value
的类型为T
,而x
的类型为object
。 C# 的强类型本质要求您告诉编译器“看,我知道这可能不安全,但是您可以尝试为我做这件事吗,无论是通过转换还是拆箱还是其他方式?谢谢!”2.
如果
x
是派生自T
的类的实例怎么办?或者,如果x
是实现接口的类的实例,而T
就是该接口?现在,您将返回一个ValueWrapper
实例,该实例指示字典中不存在具有键key
的对象。我认为这与大多数人的期望非常违反直觉。此外,如果您不想在
dictionary
不包含与键key
匹配的值时抛出,我认为您应该将您的方法重命名为TryGetValue< /code>,接受
ValueWrapper
类型的out
参数,并返回指示成功/失败的bool
。3.
针对您的评论,这是一种解决方案。
用法:
您必须添加参数检查等。
A few comments:
t.Value = (T)x;
The cast is necessary. This is because
t.Value
is of typeT
andx
is of typeobject
. The strongly-typed nature of C# requires that you tell the compiler "look, I know this might unsafe but can you just try to do it for me anyway, either by conversion or unboxing or whatever? Thanks!"2.
What if
x
is an instance of a class that derives fromT
? Or ifx
is an instance of a class that implements an interface andT
is that interface? Right now, you will return a instance ofValueWrapper<T>
that indicates there was no object in the dictionary with the keykey
. I would argue this is very counterintuitive to what most people expect.Additionally, if you're not going to throw up when
dictionary
does not contain a value matching the keykey
, I think you should rename your method toTryGetValue
, accept aout
parameter of typeValueWrapper<T>
, and return abool
indicating success/failure.3.
Responding to your comment, here's one solution.
Usage:
You'll have to add parameter checking etc.