【问题标题】:C# List of generic class that implements a type-specific function [closed]C#实现特定类型函数的泛型类列表[关闭]
【发布时间】:2021-03-01 02:08:12
【问题描述】:

更新: This 是我试图要求的,但不知道如何。

基本上我需要的是一个值列表,但我不在乎这些值是什么类型,只要它们实现了一些不同的功能。像这样的:

List<MagicType> values1 = new List<MagicType>();
List<MagicType> values2 = someAlreadyExistingListOfMagicType;

Vector3 position = someVector3;
Quaternion rotation = someQuat;
bool sleeping = false;

values1.Add(new MagicType<Vector3>(position));
values1.Add(new MagicType<Quaternion>(rotation));
values1.Add(new MagicType<bool>(sleeping));

List<byte> result = new List<byte>();

foreach(MagicType value1 in values1)
{
    foreach(MagicType value2 in values2)
    {
        if(value1.Compare(Value2))
        {
            result.AddRange(value1.GetBytes());
        }
    }
}

我不确定我想要的是否正常。我试过这样做:

public class MagicClass<T>
{
    private T value;
    
    public MagicClass(T value)
    {
        this.value = value;
    }
    
    public bool Compare(T a, T b)
    {
        return a == b;
    }
    
    public byte[] GetBytes()
    {
        //somehow return byte array
    }
}

但这抱怨操作符 '==' 不能应用于类型 T 和 T。

我确信这里一定有一个简单的解决方案,但我在这方面花了很长时间,我无法再思考了。我该如何解决我的问题?

【问题讨论】:

  • “我需要一种方法让 IMagicType 了解类型是什么” -- 也许 你应该让它通用吗?你的问题很难理解。您在上面显示的要添加到列表中的值,不能添加到列表中,因为它们不实现您的任意接口 IMagicType,不管是什么。 也许而不是IMagicType,你只想要IComparable?也许您不应该发布这个问题,直到您解决了您“难以理解如何提出这个问题”的问题。就目前而言,还不清楚。
  • 您是否尝试让IMagicType 继承自IComparable&lt;IMagicType&gt; 和一些自定义IByteConvertible&lt;IMagicType&gt;
  • @PeterDuniho 我希望至少清楚我想要什么,即使我不知道如何实现它。我只需要一个值列表,但我不在乎这些值是什么类型,只要它们实现了一些不同的功能。我已经编辑了这个问题,希望能更清楚我在追求/尝试过什么。
  • @JL0PD 我不确定我在想什么将其命名为IMagicType 以暗示它是一个接口。我很确定这根本不是我想要的。我已经编辑了这个问题,所以希望它现在更有意义。当你说让IMagicType 继承自IComparable&lt;IMagicType&gt; 时……是这样的吗?类/接口能否继承自第一类类型的泛型类?
  • 这看起来像XY Problem为什么您首先要这样做?

标签: c# generics


【解决方案1】:

但这抱怨运算符 '==' 不能应用于类型 T 和 T。

public class MagicClass<T>
{
    private T value;
    
    public MagicClass(T value)
    {
        this.value = value;

    
    public bool Compare(T a, T b)  // what is this?
    {
        return a == b;
    }
    
    public byte[] GetBytes()
    {
        //somehow return byte array
    }
}

您没有在该函数中定义operator== 应该是什么。

事实上,你不仅没有定义所需的运算符,还试图在一个名为Compare 的随机函数中使用它,按照惯例返回一个bool,它返回一个比较结果。框架提供的用于测试相等性的函数被称为Equals,也许很奇怪。

所以,一点点正确的代码就能马上修补你的课程!

public class MagicClass<T>: IEquatable<MagicClass<T>>
{
    private T value;

    public MagicClass(T value)
    {
        this.value = value;
    }

    public override bool Equals(object objB) => 
        objB is MagicClass<T> b ? value == b.value : false;

    public bool Equals(MagicClass<T> b) => value == b.Value;

    public byte[] GetBytes()
    {
        //somehow return byte array
    }
}

我为您提供了一个标准的IEquatable&lt;&gt; 接口实现。请记住,您缺少的另一段代码是覆盖 GetHashCode() 函数。如果您正确设置项目,您将收到一条长警告。

【讨论】:

  • 我很困惑,但这清楚地表明了我的意图的另一个问题。我的目的是让Compare 函数智能地比较不同的类型。所以 Vector3s 可能需要在幅度上相差超过 0.01f 才能算作不同,但这意味着我需要为每种类型实现 MagicClass。或者其他的东西。好吧,我显然不知道我在说什么。等我把事情理清了,我会回来的。此外,值得一提的是,您的代码无法修复 one of the issues。为什么我必须定义==
  • @Clonkex 这是同一个问题。您还没有定义== 运算符,那么当我们编写value == b.value 时,编译器如何知道要做什么您需要另一种方法来定义T 上的相等性。也许T 本身需要约束where T : IEquatable&lt;T&gt; 你可以改为调用value?.Equals(b.value)
  • @Charlieface 我不明白为什么我需要定义==(或者甚至如何定义)这个和我创建的所有其他类有什么区别?在我的生活中,我从来不需要定义==。我确定我遗漏了一些明显的东西,但我真的不明白为什么它不知道 T 会是什么。如果它知道 T 将是什么(它肯定必须这样做,因为这是泛型的全部意义),那么它肯定可以愉快地比较这些值,因为它知道它们的类型。
  • @Clonkex 首先,通常可以定义这样的运算符public static operator ==(... 在这种情况下你显然不能,因为你没有T 来定义它。编译器不知道T 是否已经定义了==,它可能是一个没有定义== 的结构。如果您将 T 限制为 where T: class 类,那么它确实知道。 “泛型的重点”是告诉编译器T 可以替换为实际类型。但是,如果我们需要例如 T 具有某些属性,我们必须将其限制为仅允许满足该属性的类型
  • 啊啊啊好吧,现在我们到了某个地方。我没有考虑到结构可能无法自动测试是否相等。我几乎从不使用结构,所以这不是我以前遇到过的事情(所有事情都是第一次)。我猜是因为它是一种值类型,所以它不像比较引用那么简单。现在我也明白你为什么建议where T : IEquatable&lt;T&gt;了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-27
  • 2012-01-28
  • 1970-01-01
相关资源
最近更新 更多