gpt4 book ai didi

c# - Curiously Recurring Template Pattern 是否有替代方案?

转载 作者:行者123 更新时间:2023-11-30 15:10:17 26 4
gpt4 key购买 nike

在过去的几周里,curiously recurring template 令我有些头疼。模式。

继我的这两个问题之后:

如何改进以下示例:

public class DocketType : Enumeration<DocketType, int, string>
{
public static DocketType Withdrawal = new DocketType(2, "Withdrawal");
public static DocketType Installation = new DocketType(3, "Installation");

private DocketType(int docketTypeId, string description)
: base(docketTypeId, description) { }
}

我想要一个不需要在 Enumeration 中重复的静态方法类:

public abstract class Enumeration<TEnum, X, Y> : IComparable 
where TEnum : Enumeration<TEnum, X, Y>
{
protected Enumeration(X value, Y displayName)
{
AddToStaticCache(this);
}
public static TEnum Resolve(X value)
{
return Cache[value] as TEnum;
}
}

这个问题,正如您将从我的第二个链接问题中看到的那样,是对 Enumeration<DocketType, int, string>.Resolve(X value); 的调用不会导致 DocketType要实例化的静态对象。

我并不反对从头开始完全重写它。我知道这是一个很大的代码味道。目前,为了让它工作,我的基类有 protected 静态方法 ChildResolve我添加了 Resolve到我的每个枚举类。讨厌的东西!

回答:

似乎没有替代该模式的好选择,所以我坚持使用该模式并从已接受的答案中汲取灵感并想出了这个:

static Enumeration()
{
GetAll();
}

public static void GetAll()
{
var type = typeof(TEnum);
var fields = type.GetFields(BindingFlags.Public |
BindingFlags.Static | BindingFlags.DeclaredOnly);

foreach (var info in fields)
{
var locatedValue = info.GetValue(null) as Enumeration<TEnum, X, Y>;
Cache.Add(locatedValue.Value, locatedValue);
}
}

这也是在 CodeCampServer MVC 示例项目中使用的相同代码,所以我觉得使用它不那么脏!

最佳答案

它不是很优雅,但像这样的东西可能会成功:

public class DocketType : Enumeration<DocketType, int, string>
{
public static readonly DocketType Withdrawal =
new DocketType(2, "Withdrawal");

public static readonly DocketType Installation =
new DocketType(3, "Installation");

private DocketType(int docketTypeId, string description)
: base(docketTypeId, description) { }
}

public abstract class Enumeration<TEnum, TId, TDescription> : IComparable
where TEnum : Enumeration<TEnum, TId, TDescription>
{
private static readonly Dictionary<TId, TEnum> _cache;

static Enumeration()
{
Type t = typeof(TEnum);
_cache = t.GetFields(BindingFlags.Public | BindingFlags.Static)
.Where(f => f.FieldType == t)
.Select(f => (TEnum)f.GetValue(null))
.ToDictionary(e => e.Id, e => e);
}

public static TEnum Resolve(TId id)
{
return _cache[id];
}

public TId Id { get; private set; }
public TDescription Description { get; private set; }

protected Enumeration(TId id, TDescription description)
{
Id = id;
Description = description;
}

// IComparable
public int CompareTo(object obj)
{
// TODO
throw new NotImplementedException();
}
}

关于c# - Curiously Recurring Template Pattern 是否有替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3453326/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com