Ric*_*ams 4 c# generics boxing casting
我想知道是否可以运行以下代码但没有取消装箱行: -
t.Value = (T)x;
Run Code Online (Sandbox Code Playgroud)
或者,如果有另一种方法可以做这种操作?
这是完整的代码: -
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;
}
}
Run Code Online (Sandbox Code Playgroud)
提前致谢!!
理查德.
一些评论:
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;
Run Code Online (Sandbox Code Playgroud)
如果x
是派生自的类的实例T
怎么办?或者,如果x
是实现接口的类的实例并且T
是该接口?现在,您将返回一个实例ValueWrapper<T>
,表明字典中没有带密钥的对象key
.我认为这与大多数人的期望非常违反直觉.
另外,如果在dictionary
不包含与键匹配的值时不打算抛出key
,我认为您应该将方法重命名为TryGetValue
,接受out
类型的参数ValueWrapper<T>
,并返回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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
var dict = new Dictionary<string, IValueWrapper>();
dict.Add("hello", 5);
ValueWrapper<int> value;
dict.TryGetWrappedValue("hello", out value);
Run Code Online (Sandbox Code Playgroud)
你必须添加参数检查等.
归档时间: |
|
查看次数: |
21755 次 |
最近记录: |