c# - 不可能在 .NET 中继承 2 个基类?

所以我读到在.net 中不可能继承第二个基类。那么如何创建一个对象,为 2 个类提供 2 个功能?例如,我有一个我想成为工具和武器的对象。第一个是 public class SmithHammer : BaseTool 第二个看起来像 public class SmithHammer : BaseBashing 这两个类 BaseTool 和 BaseBashing 显然不能同时用于同一个项目。作为一种武器,我用这种方式编码以调用基类 BaseBashing。

{
    [FlipableAttribute( 0x13E3, 0x13E4 )]
    public class SmithyHammer : BaseBashing
    {
        
        public override string Damage { get { return WeaponControl.Settings.SmithyHammerDamage; } }

        public override int OldStrengthReq { get { return 45; } }
        public override int OldMinDamage { get { return 6; } }
        public override int OldMaxDamage { get { return 18; } }
        public override int OldSpeed { get { return 40; } }

        public override int InitMinHits { get { return 31; } }
        public override int InitMaxHits { get { return 60; } }

        [Constructable]
        public SmithyHammer()
            : base(0x13E3)
        {
            Weight = 8.0;
            Layer = Layer.OneHanded;
            Name = "Smith Hammer";
        }

        public SmithyHammer(Serial serial)
            : base(serial)
        { }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write(0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            var version = reader.ReadInt();
        }
    }
}

在第二次使用中,我将其作为工具

namespace Server.Items
{
    [FlipableAttribute( 0x13E3, 0x13E4 )]
    public class SmithHammer : BaseTool
    {
        public override CraftSystem CraftSystem{ get{ return DefBlacksmithy.CraftSystem; } }

        [Constructable]
        public SmithHammer() : base( 0x13E3 )
        {
            Weight = 8.0;
            Layer = Layer.OneHanded;
        }

        [Constructable]
        public SmithHammer( int uses ) : base( uses, 0x13E3 )
        {
            Weight = 8.0;
            Layer = Layer.OneHanded;
        }

        public SmithHammer( Serial serial ) : base( serial )
        {
        }

        public override void Serialize( GenericWriter writer )
        {
            base.Serialize( writer );

            writer.Write( (int) 0 ); // version
        }

        public override void Deserialize( GenericReader reader )
        {
            base.Deserialize( reader );

            int version = reader.ReadInt();
        }
    }
}

是不是不能让这个项目兼具这两个功能?

回答1

这种情况有一种机制 - https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/types/interfaces。 C# 中的类不支持多重继承,但支持实现多个接口。在这种情况下,您可以创建两个(甚至更多)代表所需合同(即接口)的接口:

public interface IBashing
{
    string Damage { get; }
    int OldStrengthReq { get; }
    // ...
    // rest of properties/methods for bashing/weapon
}

public interface ITool
{
    CraftSystem CraftSystem { get; }
    // ...
}

并在 Hammer 类中实现它们:

public class SmithHammer : IBashing, ITool
{
    public string Damage { get { return WeaponControl.Settings.SmithyHammerDamage; } }
    public int OldStrengthReq { get { return 45; } }
    public CraftSystem CraftSystem { get{ return DefBlacksmithy.CraftSystem; } }
    
    // rest of implemetations
}

客户端可以通过接口或使用https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/type-testing-and-cast来使用这个锤子类实例。例如,如果您将 IItem 接口引入到 store 库存中的所有内容(即 interface IBashing : IIteminterface ITool : IItem),它可能如下所示:

var inventory = new List<IItem>();
// add some items
// pick some i'th item:
var item = inventory[i];
var tool = item as ITool; // or use pattern matching here
if(tool != null)
{
   // use tool
}
else
{
   ....
}

使用接口共享实现并不是那么容易(除非您可以并且想要使用https://devblogs.microsoft.com/dotnet/default-implementations-in-interfaces/),但可以通过组合和包装来实现,即:

public class SmithyHammerBashing : BaseBashing
{
    public override string Damage { get { return WeaponControl.Settings.SmithyHammerDamage; } }
    public override int OldStrengthReq { get { return 45; } }
}
public class SmithHammer : IBashing, ITool
{
    private readonly SmithyHammerBashing Bashing = new SmithyHammerBashing(); // or construct some other way
    public string Damage { get { return Bashing.Damage; } }
    public int OldStrengthReq { get { return Bashing.OldStrengthReq; } }
    // the same approach for ITool
}

相似文章

twilio - DevTools 无法加载源 map

我知道Chrome开发工具中有很多关于这些警告的帖子。对于所有这些,解决方案是关闭通知“启用javascript源maps”和“启用CSS源maps”。我想知道的是如何解决这个问题,以及导致这些警告的...

随机推荐

最新文章