2017-04-12 83 views
0

我正在处理现有的自定义集合类型。该限制目前无法更改。.NET中是否有1值“类包装器”类型?

class CustomDict<TKey, TValue> 
where TValue : class 

我想使用结构类型(即bool)作为值。

是否有标准 .NET/CLR类型可用作类包围类包装器,以便下列内容有效?

new CustomDict<string, Wrapper<bool>>(..) 

隐式/显式转换将是整齐的,但不是必需的。当然,创建一个自定义类是微不足道的 - 问题是关于[使用]通用/核心类类型。

+0

哦,ayaahahah!免费积分.. SO可以作为扶手椅使用。 – user2864740

+0

问题是**为什么**添加了这个约束。创建一个包装价值类的类是非常容易的,但为了满足这个奇怪的要求,必须提供什么? –

+2

*当然,创建一个自定义类很简单*我可能会这么做。 –

回答

2

我发现这个Tuple类:

https://msdn.microsoft.com/en-us/library/system.tuple(v=vs.110).aspx

您可以使用Tuple<bool>TValue类型参数。只需拨打Create创建一个实例例如为:

Tuple.Create(true) 
+1

一个很好的答案,但是我个人认为我宁愿花30秒钟将一个自定义类鞭打在一起,以避免真正难看的'Item1'属性访问'Tuple'中的值。 –

+0

@MattBurland我同意。我也确信OP是知道创建一个自定义类,他可能有一些不这样做的理由。 – Sweeper

+0

谢谢,这就是我正在寻找的东西 - 我在'C#中键入'Tuple1',并错过了'Tuple <..>'直到一分钟后的网页搜索(我也有错误的想法,即元组是值类型,这就是为什么我最终结束在MSDN上开始)!这是一个本地化的用例,除私有方法外不会流血。 – user2864740

1

正如你说你自己,这是很轻松的事情。例如:

public class StructWrapper<T> where T : struct 
{ 
    public T Value { get; private set; } 

    public StructWrapper(T val) 
    { 
     Value = val; 
    } 

    public static implicit operator T(StructWrapper<T> w) 
    { 
     return w.Value; 
    } 

    public static implicit operator StructWrapper<T>(T s) 
    { 
     return new StructWrapper<T>(s); 
    } 
} 

然后,你可以这样做:

var bw = new StructWrapper<bool>(true); 

而且由于隐式转换,你可以做的东西,如:

if (bw) 
{ 
    Console.WriteLine("True!"); 
} 

,它应该工作。

如果您需要/想实现平等,你可以添加这StructWrapper<T>

public override bool Equals(object obj) 
{ 
    if (obj is StructWrapper<T>) 
    { 
     return Value.Equals(((StructWrapper<T>)obj).Value); 
    } 
    return Value.Equals(obj); 
} 

public override int GetHashCode() 
{ 
    return Value.GetHashCode(); 
} 

public static bool operator ==(StructWrapper<T> a, StructWrapper<T> b) 
{ 
    if (System.Object.ReferenceEquals(a, b)) 
    { 
     return true; 
    } 

    if (((object)a == null) || ((object)b == null)) 
    { 
     return false; 
    } 

    return a.Value.Equals(b.Value); 
} 

public static bool operator !=(StructWrapper<T> a, StructWrapper<T> b) 
{ 
    return !(a == b); 
} 

public static bool operator ==(StructWrapper<T> a, T b) 
{ 
    return a.Value.Equals(b); 
} 

public static bool operator !=(StructWrapper<T> a, T b) 
{ 
    return !(a == b); 
} 

public static bool operator ==(T b, StructWrapper<T> a) 
{ 
    return a.Value.Equals(b); 
} 

public static bool operator !=(T b, StructWrapper<T> a) 
{ 
    return !(a == b); 
} 

这将让你做这样的事情:

var isbwTrue = bw == true; 
+0

虽然我在这个特定情况下使用Tuple ,但肯定会有一个包装更干净的情况。但是,这也说明了添加一次性代码的问题:它没有正确实现Equality(通过封装值),这会破坏这里的用法。现有的Tuple类型可以。 – user2864740

+0

这是将一个结构包装在一个类中。至于平等,你当然可以实现,如果你想 –

+0

哦,你说得对。我读错了。感谢你的回答。 – user2864740