2016-07-07 82 views
0

鉴于字典喜欢收集有以下类:创建使用常量字符串字段可能的字符串值重复

class A 
{ 
    [CustomAttribute(1)] 
    public const string X = "x"; 

    [CustomAttribute(2)] 
    public const string Y = "y"; 

    [CustomAttribute(3)] 
    public const string Z = "z"; 
} 

class B 
{ 
    [CustomAttribute(4)] 
    public const string P = "p"; 

    [CustomAttribute(5)] 
    public const string Q = "q"; 

    [CustomAttribute(6)] 
    public const string Z = "z"; 
} 

注意Z常数,它有不同的CustomAttribute参数的重复。

我想,使用反射,迭代的类和生产类字典收集与以下属性:

dict.CustomGet(A.Z) == 3 
dict.CustomGet(B.Z) == 6 

现在,我知道,我可以很容易做到:

dict.CustomGet(()=>A.Z) 

实现为:

public int CustomGet(Expression<Func<string>> expr){...} 

,并使用Expression对象来找出我正在访问哪个课程和字段,并且有内部集合,如Dictionary<Type,Dictionary<string,int>>或甚至可能是Dictionary<FieldInfo,int>,但它要求我每次写出可疑的()=>Class.ConstantName

请注意,我无法将字符串文字值更改为唯一。

以上就是我目前的问题,我觉得的问题是:我可以用另一种方式表达比告诉C#中的唯一对象传递给CustomGet代替非唯一字符串?

附注:我想比较通过的字符串的引用,但由于实习,我认为很有可能"z"ReferenceEqual另一个"z"

最后一点:这主要是为了好玩,我可以(并且很可能会)完全避免这个问题,但我想知道C#的限制是供将来参考:)

回答

0

张贴我有一个想法之后,但我不是100%确信它有多好:

修改类看起来像这样:

class A 
{ 
    [CustomAttribute(1)] 
    public readonly MyCustomString X = "x"; 

    [CustomAttribute(2)] 
    public readonly MyCustomString Y = "y"; 

    [CustomAttribute(3)] 
    public readonly MyCustomString Z = "z"; 
} 

然后创建类型:

public class MyCustomString 
{ 
    private readonly string _value; 
    public static implicit operator MyCustomString(string str) 
    { 
     return new MyCustomString{_value=str;}; 
    } 
    public static implicit operator string(MyCustomString mcs) 
    { 
     return mcs._value; 
    } 
} 

现在,当通过像CustomGet(A.X)我可以只使用传递的对象(public int CustomGet(MyCustomString mcs);),因为它将被视为不同,即使它拥有相同_value

这是多么疯狂/不好?

0

子类化字符串可能是最好的方法。它确保每个实例都是唯一的,并且可以独一无二地比较,而不用担心碰撞。您需要使MyCustomString中的_value字符串不是只读的,因为它需要写在对象初始化上。

如果您想进一步“扩展”它,您可以将类本身传递到MyCustomString初始化中。

如:

public readonly MyCustomString Z = new MyCustomString(A.class, "Z"); 

这样,你可以做两个MyCustomString实例之间的完全平等的操作。您还需要重写MyCustomString中的GetHashCode函数以使您的类可以正常使用Dictionary类(more detail here