基于泛型接口获取类的对象

时间:2016-04-08 10:32:00

标签: c# generics compare

我有以下实现来比较两个对象。

public interface IEqualityDefinition<T>
{
    bool Compare(object source, T target);
}

public class BlockEqualityDefinition : IEqualityDefinition<Block>
{
    public bool Compare(object source, Block target)
    {
        // compare stuff..
        return false;
    }
}

我使用通用接口来指定我想要比较的类。 接下来我有以下方法:

public bool Compare(object source, object target)
{
    // Here i want something else
    IEqualityDefinition definition = new BlockEqualityDefinition();

    return definition.Compare(source, target);
}

在这个方法中,我想基于'target'参数实例化一个类。例如,当'target'参数包含'Block'对象时,我希望调用正确的EqualityDefinition类来为我做比较。

最好的方法是什么?我现在无法理解。 谢谢您的帮助!

2 个答案:

答案 0 :(得分:0)

我头脑中的两个选项:

  • 在存储实施的代码中创建地图

    Dictionary<Type, IEqualityDefinition>
    

    将实施添加到其中

    EqualityMap.Add(typeof(Block), new BlockEqualityDefinition)
    

    按您添加的类型查询。

    EqualityMap[target.GetType()]
    
  • 或者有一个界面,用于扫描所有已加载的程序集以查找所需的类型。就像How do i get a list of all loaded types in C#

    一样

    要不总是扫描所有已加载的类型,请将它们缓存在Map中,就像在第一个选项中一样。

答案 1 :(得分:0)

你应该看看工厂。工厂模式可以实现这一点。

(实际上不太好)来自here的示例:

class Factory
{
    /// <summary>
    /// Decides which class to instantiate.
    /// </summary>
    public static Position Get(int id)
    {
        switch (id)
        {
        case 0:
            return new Manager();
        case 1:
        case 2:
            return new Clerk();
        case 3:
        default:
            return new Programmer();
        }
    }
}

但是在你的情况下(实际上在大多数情况下)我会说你应该使用枚举而不是int - 它更好地重构,理解和阅读:

public enum EqualityDefinitions
{
    Block // or BlockEquality 
    // and more
}

然后你可以像这样使用它:

class EqualityDefinitionFactory
{
    /// <summary>
    /// Decides which class to instantiate.
    /// </summary>
    public static IEqualityDefinition Get(EqualityDefinitions definition)
    {
        switch (definition)
        {
            case EqualityDefinitions.BlockEquality:
                return new BlockEqualityDefinition();
            default:
                throw new NotImplementedException("Unknown type");
        }
    }
}