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

本文关键字:列表 对象 | 更新日期: 2023-09-27 17:53:16

我做了一台能把一种饼干变成另一种饼干的机器。

每个饼干变压器都有一个类似于消化道饼干变压器的方法:

IBiscuit Transform(DigestiveBiscuit digestiveBiscuit)方法。

是否有可能使用一个公共接口对这些进行分组,因为每个变压器的类型都不同,例如ChocolateBiscuitTransformer

IBiscuit Transform(ChocolateBiscuit chocolateBiscuit)

GingerNutBiscuitTransformer:

IBiscuit Transform(GingerNutBiscuit gingerNutBiscuit)

理想情况下,我想要实现的是一个饼干转换管理器,它可以接受任何类型的饼干,并给你一个饼干。

它会将所有的变压器加载到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总是DigestiveBiscuitTransformer中的DigestiveBiscuit,但代码会接受任何东西,这没有意义。

任何想法?

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

我认为这里不需要泛型。

这么简单:

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)

我认为这样的设计比用泛型更简洁。

我认为您可以将所有类型的饼干分组转换为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)
        }
    }
}