【问题标题】:Alternative to traits特质的替代品
【发布时间】:2021-01-19 11:55:32
【问题描述】:

我对来自 PHP 的 C# 很陌生,我遇到了一个问题,对于哪些特性来说是完美的,但我知道 C# 不支持特性。解决这个问题的最佳方法是什么?

在 Godot 中,我想通过添加一些动画方法来让自己更轻松地制作动画,根据 PHP,我会做这样的事情。方法也不能是静态的。

public trait SpriteAnimator {

    public void Animate(string animation)
    {
        // DO SOMETHING
    }
    
}

public class Actor : KinematicBody2D
{
    use SpriteAnimator;
    
    public override void _Ready()
    {
        Animate("run");
    }
}

我将如何在 C# 中解决这个问题?

【问题讨论】:

  • 看看扩展方法,将它们与接口一起使用。相关:stackoverflow.com/questions/6644668/mixins-with-c-sharp-4-0
  • @Jordão 据我所见,这些只能是静态的,这违背了这个目的。
  • 没关系,我以为你只能做静态,但它们的工作方式与正常情况略有不同。谢谢@Jordão

标签: c# .net godot


【解决方案1】:

C# 没有任何与 PHP 的 trait 系统完全类似的东西,但它的某些方面可以使用 interfaces、扩展方法和偶尔使用默认接口方法来模拟。

trait 最简单的用法是在类中添加方法而不进行子类化。扩展方法允许您根据对象的类型有效地向对象添加方法。只有在目标类型上公开可见的成员才能在扩展中访问。

public interface INamed
{
    string Name { get; }
}

public static class DemoExtensions
{
    // This is available on instances of any type
    public static void SayHello(this object self)
    {
        Console.WriteLine("Hello.")
    }

    // This one will work on instances whose type implements INamed
    public static void SayHello(this INamed self)
    {
        Console.WriteLine($"Hello {self.Name}.");
    }
}

静态trait 数据成员更难。虽然您可以在扩展类(上面的DemoExtensions)中定义静态字段或属性,但该值在运行扩展方法的所有类型之间共享。如果您需要基于调用该方法的对象类型的静态值,那么您需要在扩展类中使用 Dictionary<type, ...> static 手动处理。

另一个限制是扩展方法需要一个对象来调用:

public class MyClass : INamed
{
    public string Name { get; }

    public MyClass(string name)
    {
        Name = name;
    }

    public void DoSomething()
    {
        this.SayHello();
    }
}

注意DoSomething 中的this.SayHello(); 行。如果你去掉this. 部分,程序将无法编译。

默认接口方法也可以用作一种扩展,但您必须先将类型强制转换为接口,然后才能访问它们。没有this.SayHello();,现在是((INamed)this).SayHello();,这还不是最糟糕的。他们有自己的位置,但大多数情况下它对我没有用。您的里程可能会有所不同。

从 C#9 开始,除了方法之外,无法添加扩展类型,我非常怀疑我们是否会在未来的任何时候获得扩展属性。您必须自行解决 trait 属性的问题,直到这种情况发生变化。

【讨论】:

    【解决方案2】:

    Alternative to traits 这是来自 Jordão。我不知道你在静态方法中得到了你调用它的对象。

    【讨论】:

    • 这不是答案。如果您要回答自己的问题,请确保您将其写下来,就好像您在为其他人的问题提供完整的答案一样。
    猜你喜欢
    • 1970-01-01
    • 2017-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 2012-01-25
    相关资源
    最近更新 更多