您可以将通用对象分组到列表中吗?

时间:2015-06-04 15:41:33

标签: c# generics

我制作了一台将饼干从一种类型转换为另一种类型的机器。

每个BiscuitTransformer都有像DigestiveBiscuitTransformer这样的方法:

IBiscuit Transform(DigestiveBiscuit digestiveBiscuit)方法。

是否可以使用通用接口对这些进行分组,因为每个变换器的类型不同,例如: ChocolateBiscuitTransformer

IBiscuit Transform(ChocolateBiscuit chocolateBiscuit)

GingerNutBiscuitTransformer:

IBiscuit Transform(GingerNutBiscuit gingerNutBiscuit)

理想情况下,我想要实现的是一个BiscuitTransformationManager,它将接收任何类型的饼干,然后给你一个IBiscuit。

它会将所有变形金刚加载到List<IBiscuitTransformer>,然后IBiscuitTransformer也会公开Type InputBiscuitType {get;},这样您就可以将它与传入的饼干类型进行比较:

BiscuitTransformationManager:

IBiscuit Transform<T>(T biscuit)
{
    var transformer = LoadTransformers().Single(c => c.InputBiscuitType == typeof(T));

    return transformer.Transform(biscuit);
}

我不认为是有效的,因为变形金刚会期待一种具体的类型,而不是T。

问题是我无法弄清楚如何对它们进行分组,如果我创建接口方法Transform<T>我不知道如何实现它,因为T总是{{1}在DigestiveBiscuit中但代码会接受任何内容,这没有任何意义。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我认为你不需要这里的仿制品。

这个怎么样:

IBiscuit Transform(IBiscuit biscuit)
{
    var transformer = LoadTransformers().Single(c => c.InputBiscuitType == biscuit.GetType());

    return transformer.Transform(biscuit);
}

但是,当然,这意味着每个变换器应该具有匹配的方法签名而不是特定于类型,我认为这实际上是正确的方法。

所以而不是

IBiscuit Transform(DigestiveBiscuit digestiveBiscuit)

将变压器的签名(以及其他签名)更改为:

IBiscuit Transform(IBiscuit digestiveBiscuit)

我认为这种设计比使用仿制药更简洁,更简单。

答案 1 :(得分:0)

我认为您可以将所有类型的饼干分组,以便在BiscuitTransformManager中对其进行转换。

public interface ITransformedBiscuit {}

public class DigestiveBiscuit : ITransformedBiscuit {}

public class ChocolateBiscuit : ITransformedBiscuit {}

public class BiscuitTransformManager 
{
    IBiscuit Transform(ITransformedBiscuit biscuit)
    {
        // Use a reflection in here 
        var instances = from t in Assembly.GetExecutingAssembly().GetTypes()
            where typeof(ITransformedBiscuit).IsAssignableFrom(t)
                     && t.GetConstructor(Type.EmptyTypes) != null
            select Activator.CreateInstance(t) as ITransformedBiscuit;

        foreach (var instance in instances)
        {
            instance.Transform(biscuit)
        }
    }
}