C# 内部类构造函数。。。这行吗?
好的,对不起,伙计们,我知道你们会告诉我我需要搜索和搜索,但我已经这样做了,我非常确定我的假设是正确的,这将按照我想要的方式工作,但我想我会在这里问一下,并试着在我的学习经验上获得一些专业帮助,因为unity answers不是很好 无论如何,我正在尝试构建另一个MMORPG,同时我也在学习c sharp。我有一个职业类(玩家的职业,如法师、骑士等),我想在创建玩家类的同时创建它,所以我需要使用一个id来决定他们继承的职业和属性值 这就是我所拥有的,当我努力做到这一点时,它会起作用吗?还是我做错了什么可怕的事 编辑C# 内部类构造函数。。。这行吗?,c#,unity3d,C#,Unity3d,好的,对不起,伙计们,我知道你们会告诉我我需要搜索和搜索,但我已经这样做了,我非常确定我的假设是正确的,这将按照我想要的方式工作,但我想我会在这里问一下,并试着在我的学习经验上获得一些专业帮助,因为unity answers不是很好 无论如何,我正在尝试构建另一个MMORPG,同时我也在学习c sharp。我有一个职业类(玩家的职业,如法师、骑士等),我想在创建玩家类的同时创建它,所以我需要使用一个id来决定他们继承的职业和属性值 这就是我所拥有的,当我努力做到这一点时,它会起作用吗?还是我做错
using UnityEngine;
using System.Collections;
//DONE: abstract: a personage can't be "Vocation", but Mage, Warrior, Archer...
public abstract class Vocation
{
//DONE: just a readonly property
public int Vid {get; }
//DONE: just a readonly property
public string Name { get { return _Name; } }
protected string _Name = "None";
//DONE: let's ensure the property to be overriden
public abstract HitPointsPerLevel { get; }
public abstract ManaPointsPerLevel { get; }
//DONE: you don't want this constructor to be public, but protected only
//DONE: Assign all the data in one place
protected Vocation(int vid)
{
Vid = vid;
}
}
//DONE: do not declare derived class as inner one
internal class Mage : Vocation
{
sealed public override float HitPointsPerLevel { get { return 12f; } }
sealed public override string _Name = "Mage";
//DONE: typo constructor should have been "Mage"
public Mage() : base(1)
{
}
}
伙计们,它现在看起来怎么样?除了构造函数名(
战士
而不是法师
)之外,代码可以工作
我确实想知道为什么Mage
必须是cavity
的内部嵌套类。这有什么用
我可以理解为什么要将其设置为内部:您不想让外部程序集创建实例,您可以通过工厂来创建实例。但是,没有理由使类嵌套。基类可以独立存在。只需拉出嵌套类,使用基类上的protected
成员就可以在基类和派生类之间进行通信
一个小提示:您可以在此处使用this
而不是base
:
public Mage(int vid) : base(vid)
{
this.Vid = 1;
this.Name = "Mage";
}
除了其他答案之外,没有什么值得评论的,但它们都是在代码审查的背景下进行的。也许这在codereview.stackexchange.com中更好
首先(这取决于风格)-我尽量避免使用名为Vid
的变量-职业ID
没有问题-最好是足够的描述性
其次,与这个问题更相关的是,我不确定你的Mage
/人,从语义上来说,是一种职业,所以它不应该继承它。也许这是一个人的职业,但这不是职业本身——它可能不会扩展职业功能。这是继承的唯一目的
你是不是为了实践而试图在继承的概念上吹牛
另外,在C#6中,有表达式体属性,因此可以稍微压缩代码:
public string Name => "None";
虽然在我看来这些都是常数。这基本上需要一个大的重新设计,从封装的OOP基础开始并保持简单。我建议重新设计实现
using UnityEngine;
using System.Collections;
//DONE: abstract: a personage can't be "Vocation", but Mage, Warrior, Archer...
public abstract class Vocation
{
//DONE: just a readonly property
public int Vid {get; }
//DONE: just a readonly property
public string Name {get; }
//DONE: let's ensure the property to be overriden
public abstract HitPointsPerLevel { get; }
//DONE: you don't want this constructor to be public, but protected only
//DONE: Assign all the data in one place
protected Vocation(int vid, string name)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentNullException("name");
Vid = vid;
Name = name;
}
}
//DONE: do not declare derived class as inner one
internal class Mage : Vocation
{
sealed public override float HitPointsPerLevel { get { return 12f; } }
//DONE: typo constructor should have been "Mage"
public Mage() : base(1, "Mage")
{
}
}
您没有使用Mage类。internal
表示只能从同一程序集中(exe、dll)访问类。如果没有进一步的背景,我想说你现在不必为此烦恼Mage
也是一个内部类,但我看不出为什么它应该是这样。我想Warrior
是一个复制粘贴错误,你的意思是Mage
?最后,为什么要传入vid
并将其分配给只读属性?那不行。如果你试过,你会看到base.Vid=1代码>产生编译器错误,因为Vid
没有setter。偶数Vid=Vid
失败并且不会执行任何操作,因为Vid
始终返回0
。其次,base.Name=“Mage”代码>也因同样的原因不起作用。您可以在职业
中设置一个受保护的字符串_Name=“None”
,然后将Name属性转换为公共字符串名{get{return{u Name}}
并在Mage
构造函数中设置字段。。。哪个叫做战士?说真的,让IDE(VisualStudio)来帮助您解决这样的错误……是的,战士部分是个错误。非常感谢你们向我解释了这么多。@corak我想我会巧妙地使用你对我的职业类的_namefor name和一些其他属性所做的方式再次感谢你为什么不把HitPointsPerLevel
也放在构造函数中?将抽象类的构造函数设置为公共或非公共都没有关系受保护…@HitPointsPerLevel:HitPointsPerLevel
可能很复杂(取决于Mage
的法力、战士的灵巧度、武器类型等)@Patrick Hofman:你说得对,但是protected
是一个很好的指示器,表明constrator被设计为仅在派生类中使用,如本答案所示,在Unity中是内部的,因为默认情况下,类被添加到全局命名空间中。只有将该类包装在命名空间中,它才有意义。法师在项目中的任何地方都可以使用。Unity不支持C#4、5甚至6。我想我可以使用它,而不是base,这是一个意外,它是内部和嵌套的。