如何创建具有嵌入式字段的结构?

How to create a structure with embedded fields?

我正在互联网上寻找相关信息,但没有成功。目标是实现一个包含10个主题(sub_1,sub_2...sub_10)的数据集,他们每个人都做了3种活动(步行,运行, jump) 各三次 (trial_1... trial_3) 相对分数。我想访问这些信息,例如:

variable = dataset.sub_1.jump.trial_2.score;

或者,至少:

variable = dataset.sub[0].task[2].trial[1].score;

因此,该结构将是一个树结构。到现在我只实现了一个“平行域”的结构:

struct dataset
{
    public string[] sub;   // 1 to 10 subjects
    public string[] task;  // 1 to 3 tasks
    public string[] trial; // 1 to 3 trials
    public int score;      // the score of the above combination
}

有什么想法吗?

using System;
using System.Collections.Generic;

namespace ConsoleApp
{
    public class Trial
    {
        public Trial(int score)
        {
            Score = score;
        }

        public int Score { get; set; }
    }

    public class Task
    {
        public List<Trial> Trials { get; } = new List<Trial>();
    }

    public class Subject
    {
        public Dictionary<string, Task> Tasks { get; } = new Dictionary<string, Task>();

        public Subject()
        {
            Tasks.Add("walk", new Task());
            Tasks.Add("run", new Task());
            Tasks.Add("jump", new Task());
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Subject player1 = new Subject();

            player1.Tasks["run"].Trials.Add(new Trial(score: 3));

            Console.WriteLine(player1.Tasks["run"].Trials[0].Score);
        }
    }
}

也许对所有内容的 class 太多了,但也许您想为某天的任务添加描述 属性 或为试用添加时间戳。那就好了。

这个问题可以通过多种方式解决。 我的解决方案有一个缺点,即不检查用户是否超出了 Score 数组的容量。

我猜数据库标签与这个问题无关

using System;
using System.Linq;

namespace ConsoleApp
{
    public abstract class Task
    {
        public string Name { get; set; }
        public int TotalScore { get { return Score.Sum(); } }
        public int[] Score { get; set; } = new int[3];
    }

    public class Walk : Task { }
    public class Run : Task { }
    public class Jump : Task { }

    public class Subject
    {
        public Walk Walk { get; set; } = new();
        public Run Run { get; set; } = new();
        public Jump Jump { get; set; } = new();
        public int TotalScore { get { return Walk.TotalScore + Run.TotalScore + Jump.TotalScore; }}
    }

    class Program
    {
        static void Main(string[] args)
        {
            var subject = new Subject();

            // Adding score to specific trials
            subject.Run.Score[0] = 50;
            subject.Run.Score[1] = 40;
            subject.Run.Score[2] = 60;

            subject.Jump.Score[0] = 40;
            subject.Jump.Score[1] = 80;
            subject.Jump.Score[2] = 100;

            // Output score of 1. trial for Walk task
            Console.WriteLine(subject.Walk.Score[0]);

            // Output total score as a sum of all trials for Jump task
            Console.WriteLine(subject.Jump.TotalScore);

            // Output total score as a sum of all trials in all tasks
            Console.WriteLine(subject.TotalScore);

            // ERROR CASE: this will be exception
            subject.Jump.Score[3] = 100;
        }
    }
}
    public class Subject
{
    private Dictionary<string,Activity> _activities { get; }= new Dictionary<string, Activity>();

    public Activity this[string activity]
    {
        get
        {
            if (!_activities.Keys.Contains(activity))
                _activities[activity] = new Activity();
            return _activities[activity];
            
        }
        set
        {
                _activities[activity] = value;
        }

    } 
    public int Score => _activities.Values.Sum(x => x.Score);
}

public class Activity
{
    private Dictionary<int, Trial> _trials { get; } = new Dictionary<int, Trial>();
    public Trial this[int trial]
    {
        get
        {
            if (!_trials.Keys.Contains(trial))
                _trials[trial] = new Trial();
            return _trials[trial];
        }
        set
        {
                _trials[trial] = value;
        }

    }
    public int Score => _trials.Values.Sum(x => x.Score);
}

public class Trial
{
    public int Score { get; set; }
}
public class Answer
{
    public void DoSomething()
    {

        Subject Mindy = new Subject();
        Mindy["curling"][1].Score = 5;
        Mindy["bowling"][1].Score = 290;
        Console.WriteLine(Mindy.Score);
    }
}

这就是我猜您认为您需要的...但是从您的问题来看,我认为您对 C# 还是个新手,可能需要重新考虑您的概念。它看起来像是一种非常面向数据库的问题查看方式,所以也许您可能想看看 dapper 以更接近地匹配您的数据库。

此外,避免使用类名 Task,如果您开始使用多线程(System.Threading.Task 是 .NET 框架组件),这只会在我看来造成混乱