C# - 重置 class 或结构上的结构值
C# - Reset the value of struct on class or struct
我正在尝试使用 Unity 编写一些脚本,但我在理解结构的工作原理时遇到了一些问题。
从基本代码开始:
public class Engine : MonoBehaviour {
public Hero selectedHero;
public List<Hero> heroes;
public struct Hero {
public string name;
public Hero(string n) {
name = n;
}
}
}
首先我尝试为 select/unselect 做一些功能..
/* ... */
public Hero getSelected(Hero h) {
return selectedHero;
}
public void setSelected(Hero h) {
selectedHero = h;
}
public bool hasSelected(Hero h) {
return (selectedHero != null);
}
public void clearSelected() {
selectedHero = null; // This is not working ! :'(
}
/* ... */
我收到了这个错误:
Cannot convert null to Hero
because it is a value type
我阅读了很多关于 C# 和 Unity 脚本的文章,答案是:
A struct can't be null in the same way that an int can't be null, and
a float can't be null - they're all value types
但是?什么是真正的解决方案!?我使用了两个丑陋的解决方案来避免这种情况:
解决方案 #1 我可以放一个 public bool hasSelected
并且总是在使用 selected
属性之前测试这个。
解决方案 #2 是创建一个 List<Hero> selected
而不是简单的 Hero
并处理长度为 0 或 1 的情况。
是否存在更好、更干净的解决方案?!
奖金问题:如何创建一个函数 return 一个基于测试的单个英雄,我最好的(丑陋的)解决方案:
public Hero GetHero(string name) {
foreach (Hero hero in heroes) {
if (hero.name == name) {
return hero;
}
}
return null; // Not working ?! What can I return ?!
}
如果您需要您的类型可以为空,听起来您应该将 Hero
设为 class(引用类型)而不是结构(值类型)。对代码的更改将是最小的,只需交换关键字:
public class Hero {
public string name;
public Hero(string n) {
name = n;
}
}
如果有理由您应该使用 Struct 而不是 class ,那么请使用默认值来检查您的结构。
有时,当您的程序需要一个结构并且您传递一个 class 时,它的行为(或错误行为)可能会有所不同。
下面是您的两种方法的更改:
public bool hasSelected(Hero h)
{
return !(h.Equals(default(Hero)));
}
public void clearSelected()
{
selectedHero = default(Hero);
}
关于主要问题:
值类型(int、struct 等)不能在其二进制表示中表示 null,这就是 .NET 不允许的原因。但是 .NET 它具有 Nullable<T>
结构,可以为空表示添加额外的字节。
关于 select/unselect 函数
我已重构您的代码以使用结构:
public Hero GetSelected()
{
return selectedHero;
}
public void SetSelected(Hero h)
{
selectedHero = h;
}
public bool HasSelected()
{
return !(selectedHero.Equals(default(Hero)));
}
public void ClearSelected()
{
selectedHero = default(Hero);
}
关于奖金问题:
很简单,用LinQ =)
public Hero GetHero(string name)
{
return heroes.Where(w => w.name.Equals(name)).FirstOrDefault();
}
PS:'default value''Null Value'以外的
参考文献:
希望对你有所帮助
我正在尝试使用 Unity 编写一些脚本,但我在理解结构的工作原理时遇到了一些问题。
从基本代码开始:
public class Engine : MonoBehaviour {
public Hero selectedHero;
public List<Hero> heroes;
public struct Hero {
public string name;
public Hero(string n) {
name = n;
}
}
}
首先我尝试为 select/unselect 做一些功能..
/* ... */
public Hero getSelected(Hero h) {
return selectedHero;
}
public void setSelected(Hero h) {
selectedHero = h;
}
public bool hasSelected(Hero h) {
return (selectedHero != null);
}
public void clearSelected() {
selectedHero = null; // This is not working ! :'(
}
/* ... */
我收到了这个错误:
Cannot convert null to
Hero
because it is a value type
我阅读了很多关于 C# 和 Unity 脚本的文章,答案是:
A struct can't be null in the same way that an int can't be null, and a float can't be null - they're all value types
但是?什么是真正的解决方案!?我使用了两个丑陋的解决方案来避免这种情况:
解决方案 #1 我可以放一个 public bool hasSelected
并且总是在使用 selected
属性之前测试这个。
解决方案 #2 是创建一个 List<Hero> selected
而不是简单的 Hero
并处理长度为 0 或 1 的情况。
是否存在更好、更干净的解决方案?!
奖金问题:如何创建一个函数 return 一个基于测试的单个英雄,我最好的(丑陋的)解决方案:
public Hero GetHero(string name) {
foreach (Hero hero in heroes) {
if (hero.name == name) {
return hero;
}
}
return null; // Not working ?! What can I return ?!
}
如果您需要您的类型可以为空,听起来您应该将 Hero
设为 class(引用类型)而不是结构(值类型)。对代码的更改将是最小的,只需交换关键字:
public class Hero {
public string name;
public Hero(string n) {
name = n;
}
}
如果有理由您应该使用 Struct 而不是 class ,那么请使用默认值来检查您的结构。
有时,当您的程序需要一个结构并且您传递一个 class 时,它的行为(或错误行为)可能会有所不同。
下面是您的两种方法的更改:
public bool hasSelected(Hero h)
{
return !(h.Equals(default(Hero)));
}
public void clearSelected()
{
selectedHero = default(Hero);
}
关于主要问题:
值类型(int、struct 等)不能在其二进制表示中表示 null,这就是 .NET 不允许的原因。但是 .NET 它具有 Nullable<T>
结构,可以为空表示添加额外的字节。
关于 select/unselect 函数
我已重构您的代码以使用结构:
public Hero GetSelected()
{
return selectedHero;
}
public void SetSelected(Hero h)
{
selectedHero = h;
}
public bool HasSelected()
{
return !(selectedHero.Equals(default(Hero)));
}
public void ClearSelected()
{
selectedHero = default(Hero);
}
关于奖金问题:
很简单,用LinQ =)
public Hero GetHero(string name)
{
return heroes.Where(w => w.name.Equals(name)).FirstOrDefault();
}
PS:'default value''Null Value'以外的
参考文献:
希望对你有所帮助