C# 从字典中获取值<;字符串,对象>;不拆箱?
我想知道是否可以运行以下代码,但不需要取消装箱行:-C# 从字典中获取值<;字符串,对象>;不拆箱?,c#,generics,casting,boxing,C#,Generics,Casting,Boxing,我想知道是否可以运行以下代码,但不需要取消装箱行:- t.Value = (T)x; 或者如果有其他的方法来做这种手术 以下是完整的代码:- public class ValueWrapper<T> { public T Value { get; set; } public bool HasValue { get; set; } public ValueWrapper() { HasValue = false; } } c
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;
}
}
public类ValueWrapper
{
公共T值{get;set;}
公共bool HasValue{get;set;}
公共价值包装器()
{
HasValue=false;
}
}
班级计划
{
静态void Main(字符串[]参数)
{
Dictionary myDictionary=新字典();
添加(“键1”,6);
添加(“键2”,“字符串”);
var x2=GetValue(myDictionary,“key1”);
if(x2.HasValue)
WriteLine(“{0}'={1}”,“key1”,x2.Value);
其他的
Console.WriteLine(“未找到值”);
Console.ReadLine();
}
静态值包装器GetValue(IDictionary字典,字符串键)
{
ValueWrapper t=新的ValueWrapper();
对象x=null;
if(dictionary.TryGetValue(键,out x))
{
if(x.GetType()==typeof(T))
{
t、 值=(t)x;
t、 HasValue=true;
}
}
返回t;
}
}
提前谢谢
Richard.一些评论:
t.Value=(t)x代码>
t.Value
属于t
类型,x
属于object
类型。C#的强类型特性要求你告诉编译器“听着,我知道这可能不安全,但你能不能试着为我这样做,通过转换或取消打包或其他方式?谢谢!”
二,
如果x
是从T
派生的类的实例,该怎么办?或者如果x
是实现接口的类的实例,而T
是接口吗?现在,您将返回ValueWrapper
的实例,该实例指示字典中没有键为key
的对象。我认为这与大多数人的预期是背道而驰的
此外,如果您不想在dictionary
不包含与键key
匹配的值时呕吐,我认为您应该将您的方法重命名为TryGetValue
,接受类型为ValueWrapper
的out
参数,并返回指示成功/失败的bool
三,
回应你的评论,这里有一个解决方案
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;
}
}
}
公共接口{
对象值{get;set;}
bool HasValue{get;set;}
}
公共类ValueWrapper:IValueWrapper{
公共T值{get;set;}
对象IValueWrapper.Value{
获取{返回值;}
设置{this.Value=(T)Value;}
}
公共bool HasValue{get;set;}
公共价值包装器(){
this.HasValue=false;
}
公共价值包装(T值){
这个。值=值;
this.HasValue=value!=null;
}
}
公共静态类字典扩展{
公共静态无效添加(
这本词典,
字符串键,
T值
) {
ValueWrapper ValueWrapper=新的ValueWrapper(值);
dictionary.Add(key,valueWrapper);
}
公共静态bool tryGetTrappedValue(
词典,
字符串键,
out ValueWrapper值
) {
IValueWrapper-valueWrapper;
if(dictionary.TryGetValue(key,out valueWrapper)){
value=(ValueWrapper)ValueWrapper;
返回true;
}
否则{
值=空;
返回false;
}
}
}
用法:
var dict = new Dictionary<string, IValueWrapper>();
dict.Add("hello", 5);
ValueWrapper<int> value;
dict.TryGetWrappedValue("hello", out value);
var dict=newdictionary();
dict.Add(“你好”,5);
价值包装价值;
dict.tryGetTrappedValue(“hello”,输出值);
您必须添加参数检查等。否,如果您的
对象
是装箱值类型,则需要取消装箱。您希望避免取消绑定有什么原因吗?主要是为了性能,因为在我的项目中,此代码与其他内容一起使用。取消绑定将执行时间从~200ms增加到~1700ms。这仍然是可以接受的,为了我自己的利益,我只想知道是否有其他选择。这种性能的急剧下降极不可能是由于拆箱造成的。使用探查器来确定真正的瓶颈是什么。感谢您这么快的回复,我想知道是否有一种方法可以使对象不是字典中的V,但可能有其他方法来防止取消绑定,因为它可能非常慢。另外,我已经改变了我的方法来引用ValueWrapper并返回true/false,老实说,我没有想到这一点。它应该是out
,而不是ref
@Richard Adnams:我怀疑这会导致性能问题,但你只能知道是否需要配置文件。但是,请参阅我的编辑,了解解决您试图解决的问题的一种方法。谢谢您,杰森,您帮了大忙。。现在去喝杯咖啡,消化一下这个:)!
var dict = new Dictionary<string, IValueWrapper>();
dict.Add("hello", 5);
ValueWrapper<int> value;
dict.TryGetWrappedValue("hello", out value);