【问题标题】:Fields constraints for generic class - C#泛型类的字段约束 - C#
【发布时间】:2017-09-11 17:28:36
【问题描述】:

我想在 C# 中创建一个库,它可以对 Point 对象进行一些工作,但在 C# 中有很多框架,其中有很多 Point 的实现:Point、Vector2f(统一)、Vector2f(单游戏)、Vector3f ...而且我希望我的图书馆能与所有这些人一起使用。

唯一的限制是对象具有属性 X 和 Y 并且 X 和 Y 必须实现 IComparable 接口。问题是我找不到不使用反射的方法来做到这一点(不是我认为的最佳方法)。

我不希望所有类 Point 都从我的接口继承,但我希望它们有 2 个字段/成员 X 和 Y。

有没有办法做到这一点?喜欢

class MyAlgo<T> : where T has X and Y properties {}

【问题讨论】:

  • 为什么不让他们继承接口呢?它出什么问题了?你可以在接口中声明你的属性,这会让你的生活更简单
  • @FCin - 他不能让它们从他的接口继承......那些是来自不同框架的现有类
  • @GiladGreen 哦,我误解了他的问题。
  • @FCin - 不用担心 :) 无论如何,这是个好主意
  • 大部分是struct 而不是class 有很好的理由,所以请记住这一点

标签: c# unity3d monogame


【解决方案1】:

您不能在编译时检查它,因为如果您不希望所有类都继承一个公共接口或创建大量适配器,C# 无法满足您的需求。

在运行时,反射是您实现此目的的唯一方法。反射并不总是那么糟糕,它只取决于你如何实现事物。事实上,反思的第一个问题是性能。

如果您在每次调用中都使用它,则可能会带来很大的开销。但是,例如,如果您在静态构造函数中对其进行检查,则检查将只应用一次,并且在名义执行时无需任何开销即可完成工作。

class MyAlgo<T>
{
    static private Func<T, int> X;
    static private Func<T, int> Y;

    static MyAlgo()
    {
        //check here!
        var type = typeof(T);
        var x = type.GetProperty("X");
        if (x == null) { throw new NotSupportedException($"missing X property in { type }"); }
        var y = type.GetProperty("Y");
        if (y == null) { throw new NotSupportedException($"missing Y property in { type }"); }

        // you can store delegate to retreive X & Y in static fields.
        MyAlgo<T>.X = Delegate.CreateDelegate(typeof(Func<T, int>), x.GetGetMethod());
        MyAlgo<T>.Y = Delegate.CreateDelegate(typeof(Func<T, int>), y.GetGetMethod());
    }
}

【讨论】:

  • 在 C# 中没有特征(如在 Rust 中)的一个很好的解决方法。在编写适用于我自己的数据类型和第三方数据类型的算法时,我不得不多次这样做。
【解决方案2】:

您在这里所说的称为Duck Typing。 (如果它长得像鸭子,叫起来像鸭子,那一定是鸭子吧?)。

C# 并不完全支持传统意义上的鸭子类型。大多数强类型编译语言没有这个特性(afaik)。但是,正如您在 Wikipedia 上看到的那样,您或许可以改用 dynamic

如前所述,反射确实是唯一的方法,我理解它dynamic 的方式实际上只是在引擎盖下使用反射。如果性能是一个问题(在这种情况下可能是),您应该尝试几种不同的方法并进行测量。 quick google 似乎表明它相当复杂,但至少值得一试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多