c# - 在 C# 中使用泛型和接口(interface)时如何避免强制转换

标签 c# generics interface

在下面的代码中,IPointIPointGroup是现有接口(interface)的缩写版本,定义了如何在大型应用程序的许多部分之间共享数据。

RefPoint<T> 的缩写通用实现和PointGroup<T>用于处理大量点的新子系统中,因此需要考虑最大限度地减少处理点所需的重复和转换。

代码底部说明了两个问题:

  1. 为了通过通用接口(interface)处理所有点,我采用的方法需要转换每个点
  2. 我无法通过 IPointGroup<T> 转换或以其他方式处理这些点通用接口(interface)。

如果您对我所采取的方法提出建议/改进,我将不胜感激。我对 C# 泛型还很陌生,所以我可能会遗漏一些明显的东西。

using System;

namespace Generic
{

public interface IPoint { }
public interface IPointGroup
{  void Add( IPoint x );
}

public interface IPointGroup<T> where T : IPoint
{  void Add( T x );
}

public class RefPoint<T> : IPoint
{
    public int X, Y;
    T _refersTo;

    public RefPoint( int x, int y, T refersTo )
    {
        X = x;
        Y = y;
        _refersTo = refersTo;
    }
    public T refersTo()
    {  return _refersTo;
    }
}

public class PointGroup<T> : IPointGroup where T : IPoint
{
    internal void Add( T y )
    {
        Console.WriteLine("In Add( T y )");
    }
    public void Add( IPoint x )
    {
        Console.WriteLine("In Add(IA x)");
        Add((T)x);
    }
}

public class Swerve : IPoint { }
public class HardBrake : IPoint { }
public class StopSign { };

class Program
{
    static void Main( string[] args )
    {
        PointGroup<Swerve> swerves = new PointGroup<Swerve>();
        PointGroup<HardBrake> hardBrakes = new PointGroup<HardBrake>();
        PointGroup<RefPoint<StopSign>> stopSigns = new PointGroup<RefPoint<StopSign>>();
        PointGroup<IPoint> all = new PointGroup<IPoint>();

        Swerve s = new Swerve();
        swerves.Add(s);

        HardBrake h = new HardBrake();
        hardBrakes.Add(h);

        StopSign ss = new StopSign();
        RefPoint<StopSign> ss_ref = new RefPoint<StopSign>(1,1,ss);
        stopSigns.Add(ss_ref);

        // Problem #1: Each element is cast
        all.Add(s);
        all.Add(h);
        all.Add(ss_ref);

        // Problem #2: Can't cast as follows
        // IPointGroup<Swerve> iSwerves = (IPointGroup<Swerve>)swerves;
        // IPointGroup<HardBrake> iHardBrakes = (IPointGroup<HardBrake>)hardBrakes;
        // IPointGroup<RefPoint<StopSign>> iStopSigns = (IPointGroup<RefPoint<StopSign>>) stopSigns;
        // IPointGroup<IPoint> iAll = (IPointGroup<IPoint>)all;
    }
}

}

最佳答案

在这里你实现IPointGroup :

public class PointGroup<T> : IPointGroup where T : IPoint

虽然你的意思可能是IPointGroup<T> :

public class PointGroup<T> : IPointGroup<T> where T : IPoint

此外,IPointGroupIPointGroup<T>无论如何在你的设计中都不相关。当需要接口(interface)的非泛型和泛型版本时,常见的方法是泛型继承非泛型版本;因此:

public interface IPointGroup<T> : IPointGroup where T : IPoint

另外,为了从通用版本中受益主要,请考虑显式实现非通用版本,如下所示:

public class PointGroup<T> : IPointGroup<T> where T : IPoint
{
    // implicit implementation of IPointGroup<T>.Add(T)
    public void Add(T y) { … }

    // explicit implementation of IPointGroup.Add(IPoint)
    void IPointGroup.Add(IPoint x)
    {
        Add((T)x);
    }
}

关于c# - 在 C# 中使用泛型和接口(interface)时如何避免强制转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35925258/

相关文章:

c# - Selenium WebDriver : how to count number of DIV elements in a list

c# - 如何从具有 ASPX 扩展名的 URL 提供图像?

generics - 如何避免将具体结构更改为通用结构所产生的链式 react ?

scala - (泛型)之间有什么区别吗

java - 泛型方法 - 传递对象并调用其方法

ajax - Web 应用程序如何与服务器通信?

java - 确保套接字编程中的数据传递

c# - 如何在richtextbox中建立到本地文件的链接

java - java中的MouseMotionListener如何工作?

inheritance - 使用嵌入式接口(interface)字段在 Go 中正确实现继承