接口中的C#泛型,编写泛型算法

Posted

技术标签:

【中文标题】接口中的C#泛型,编写泛型算法【英文标题】:C# generics in interface, writing generic algorithm 【发布时间】:2016-03-20 13:39:45 【问题描述】:

我需要制作一个使用多种算法来创建随机迷宫的程序。 我定义了以下类:(它是算法将使用的数据类型,而T是在特定实现中使用的类型,例如如果我使用2D矩阵表示迷宫,T将是2D点)

class Entry<T>

    private T elem; //the data saved in each entry
    public T Elem
    
        get  return elem; 
        set  this.elem = value; 
    

    public Entry(T elem)
    
        Elem = elem;
    

    public override int GetHashCode()
    
        return Elem.GetHashCode();
    

还有以下接口:

interface IRandomGeneretableMaze<T>

    void SetRandomEntrance();
    void SetRandomExit();
    List<Entry<T>> GetNextPossibleEntries(Entry<T> entry);
    void MakePath(Entry<T> entry1, Entry<T> entry2);
    void RemovePath(Entry<T> entry1, Entry<T> entry2);

它定义了一个随机生成的迷宫必须提供的行为。

interface IMaze<T>

    Entry<T> GetEntrance();
    Entry<T> GetExit();
    List<Entry<T>> GetNextMoves(Entry<T> entry);

它定义了迷宫使用的一些通用方法。 (迷宫正在以几种不同的方式实现)

interface IRandomMazeGenerator<T>

    IMaze<T> Generate(Type t);

它只定义了一个迷宫生成器,每个算法的实现方式都不同,而 t 只是要创建的迷宫类型。 (对于基于矩阵的实现可能是 1,对于基于图形的实现可能是 2,依此类推)。假设我已经做了以下课程:

class MatrixMaze : IMaze<Point2D>, IRandomGeneratable<Point2D> ...
class GraphMaze : IMaze<Node>, IRandomGeneratable<Node> ...

我的问题是当我尝试实现方法 generate 时,编译器要求我提供具体的 T,而算法不(也不应该)依赖于 T,我不想写相同的算法,仅适用于不同的 T。有没有一种方法可以编写独立于 T 的单段代码?

【问题讨论】:

你能添加错误的代码吗? 【参考方案1】:

您应该稍微更改迷宫生成器 API,以便它可以生成任何类型的迷宫:

public interface IRandomMazeGenerator<TMaze,T> where TMaze: IMaze<T>, new()
    TMaze Generate();

public class MatrixMaze : IMaze<Point2D>public MatrixMaze()..
public class EmptyMazeGenerator<TMaze,T> : IMazeGenerator<TMaze,T> where T: IMaze<T>,new()
    public TMaze Generate()
        return new TMaze();
    

或者,如果您不想在 IMaze&lt;T&gt; 上添加约束以拥有默认构造函数,请将 Func&lt;IMaze&lt;T&gt;&gt; 传递给生成器 - 然后您将拥有与 Factory 一起使用的 Builder(看它在Gang Of Four Patterns 中)

public interface IRandomMazeGenerator<T>
    IMaze<T> Generate(Func<IMaze<T>factory);


public class EmptyMazeGenerator<T> : IMazeGenerator<T>
    public IMaze<T> Generate(Func<IMaze<T>factory)
        return factory();
    

【讨论】:

以上是关于接口中的C#泛型,编写泛型算法的主要内容,如果未能解决你的问题,请参考以下文章

C# 泛型的使用

C#泛型

unity的C#学习——泛型的创建与继承泛型集合类泛型中的约束和反射

C#泛型实例详解

编写高质量代码改善C#程序的157个建议——建议35:使用default为泛型类型变量指定初始值

编写高质量代码改善C#程序的157个建议——建议42:使用泛型参数兼容泛型接口的不可变性