英文:
How to "reverse" array when setting values to make getting/setting more convenient?
问题
我使用枚举来更轻松地跟踪数据。因此,我发现使用数组来访问值比直接访问更方便。这是我的类示例:
public class Data {
// 值
int age;
int salary;
int booksOwned;
// 访问器
int[] data { get { int[] values = {age, salary, booksOwned}; return values; }}
// 构造函数
public Data(int x, int y, int z) { age = x; salary = y; booksOwned = z; }
}
我之前做过相反的事情,将数组用作基础,并具有带有值名称的get/ set(年龄 { get { return data[0]}}),但遇到了问题,因为基本对象中的值将被更新。
无论如何,这种方法一直在正常访问数据时工作得很好,但是我在使用此方法设置数据时遇到问题。如果我尝试:
Data tempData = new Data(22, 40, 3);
tempData.data[0] = 23;
我会(理所当然地)遇到问题。我是否可以创建一个 setter 来访问这些值,还是最好直接访问这些值?
添加一些上下文:
这些值只是示例,但我需要能够轻松调整这些值。在实际示例中,我有 8 种数据类型,它们都以相同的方式调整。这与我希望使用枚举的方式有些相似:
public bool Increase(Data data, DataTypeEnum dataTypeEnum) {
if (data[(int)dataTypeEnum] < 100) {
data[(int)dataTypeEnum]++;
return true;
} else {
return false;
}
}
然后在另一个地方:
int numberToAdd = 30;
while (numberToAdd > 0) {
DataTypeEnum dataToAddTo = (DataTypeEnum)Random.Range(0,3);
if (Increase(tempData, dataToAddTo)) numberToAdd--;
}
英文:
I'm using enums to make it easier to keep track of data. Because of this, I found it more convenient to access values using an array than accessing directly. Here's a sample of my class:
public class Data {
// Values
int age;
int salary;
int booksOwned;
// Accessor
int[] data { get { int[] values = {age, salary, booksOwned}; return values; }}
// Constructor
public Data(int x, int y, int z) { age = x; salary = y; booksOwned = z; }
}
I did the opposite before, using the array as the base and having get/sets with the value names (age { get { return data[0]}}), but ran into issues, as the values in the base object would be updated.
Anyway, this has been working fine to access data, but I'm having trouble when setting data with this method. If I try:
Data tempData = new Data(22, 40, 3);
tempData.data[0] = 23;
I (understandably) run into issues. Can I make a setter to access these values, or would I be better off just accessing the values directly?
edit to add context:
These values are just samples, but I need to be able to adjust these values easily. In the actual sample, I have 8 data types, and they are all adjusted in the same way. This is something along the lines of what I (would like to) use the enum for:
public bool Increase(Data data, DataTypeEnum dataTypeEnum) {
if (data[(int)dataTypeEnum] < 100) {
data[(int)dataTypeEnum]++;
return true;
} else {
return false;
}
}
then in another area:
int numberToAdd = 30;
while (numberToAdd > 0) {
DataTypeEnum dataToAddTo = (DataTypeEnum)Random.Range(0,3);
if (Increase(tempData, dataToAddTo)) numberToAdd--;
}
答案1
得分: 3
这是可怕的设计。面向对象编程是关于类,而不是命名或索引数据元素。使用myPerson.Age
或myPerson.Salary
比myData[0]
更容易理解,不是吗?
此外,每个成员都可以有自己的类型。想象一下,如果你需要一个额外的属性,比如DateOfBirth
而不是Age
,那么就会有问题,因为所有数组元素都是整数,而你需要一个DateTime
。
你甚至可以为每个成员实现自己的getter和setter函数。
我使用枚举使数据跟踪变得更容易。因此,我发现使用数组访问值比直接访问更方便。以下是我的类的示例:
public class Data {
// Values
public int Age { get; set; }
public int Salary { get; set; }
public int BooksOwned { get; set; }
}
英文:
This is horrible design. OOP is about classes, not named or index data-elements. It's way easier to understand to write myPerson.Age
or myPerson.Salary
than myData[0]
, isn't it?
Furthermore every member can have it's own type. Imagine you'd need a further property like DateOfBirth
instead of Age
. Then you get a problem, as all your arrays elements are ints, while you need a DateTime
.
You can even implement your own getter- and setter-functions for every member.
I'm using enums to make it easier to keep track of data. Because of this, I found it more convenient to access values using an array than accessing directly. Here's a sample of my class:
public class Data {
// Values
public int Age { get; set; }
public int Salary { get; set; }
public int BooksOwned {get; set; }
}
答案2
得分: 2
以下是代码部分的翻译:
看起来你想重新发明 deconstructor:
//TODO: 你可能想要使用 "readonly struct" 而不是 "class"
public class Data {
// 值:允许用户读取但不修改它们
public int Age {get;}
public int Salary {get;}
public int BooksOwned {get;}
// Deconstructor(解构器):
// 不同于数组,我们返回值
public void Deconstruct(out int age, out int salary, out int booksOwned) {
age = this.Age;
salary = this.Salary;
booksOwned = this.BooksOwned;
}
// 构造函数(使用可读的名称代替 x、y、z)
public Data(int age, int salary, int booksOwned) {
//TODO: 在此处验证输入,例如年龄不能为负数等。
this.Age = age;
this.Salary = salary;
this.BooksOwned = booksOwned;
}
}
用法:
Data data = new Data(1, 2, 3);
...
// 忽略年龄 - 注意 "_",
// 但声明并返回 mySalary 和 myBooksOwned
// 语法类似于数组,但它是一个元组
(_, int mySalary, int myBooksOwned) = data;
Console.Write($"薪水为 {mySalary},拥有 {myBooksOwned} 本书");
英文:
It seems that you want to re-invent deconstructor:
//TODO: you may want to have "readonly struct" instead of "class"
public class Data {
// Values: let's user read but not modify them
public int Age {get;}
public int Salary {get;}
public int BooksOwned {get;}
// Deconstructor:
// Instead of array we return values
public void Deconstruct(out int age, out int salary, out int booksOwned) {
age = this.Age;
salary = this.Salary;
booksOwned = this.BooksOwned;
}
// Constructor (let's use readable names instead of x, y, z)
public Data(int age, int salary, int booksOwned) {
//TODO: Validate input here, e.g. age must not be negative etc.
this.Age = age;
this.Salary = salary;
this.BooksOwned = booksOwned;
}
}
Usage
Data data = new Data(1, 2, 3);
...
// ignore age - note "_",
// but declare and return mySalary and myBooksOwned
// The syntax is similar to array, but it is a tuple
// which allows you to have different types for different variables
(_, int mySalary, int myBooksOwned) = data;
Console.Write($"Salary is {mySalary}, owned {myBooksOwned}");
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论