【问题标题】:Referencing nested class objects in C#在 C# 中引用嵌套类对象
【发布时间】:2016-03-21 11:05:36
【问题描述】:

我想要一个有几个嵌套类的类,这样当我创建一个新的父类时,每个嵌套类的对象都会被创建,我可以全局引用每个嵌套类中的变量。

这是我当前的代码:

公开课 StockChecklist
{
  公共类 qty1p1 { 公共字符串标签 = "uniqueval23456";公共字符串值 = "";公共字符串引用 = ""; }
  公共类 qty1p2 { 公共字符串标签 = "uniqueval3736";公共字符串值 = "";公共字符串引用 = ""; }

  公共类 qty2 { 公共字符串标签 = "uniqueval97357";公共字符串值 = "";公共字符串引用 = ""; }

  公共类 qty3p1 { 公共字符串标签 = "uniqueval88356";公共字符串值 = "";公共字符串引用 = ""; }
  公共类 qty3p2 { 公共字符串标签 = "uniqueval62346";公共字符串值 = "";公共字符串引用 = ""; }
  公共类 qty3p3 { 公共字符串标签 = "uniqueval09876";公共字符串值 = "";公共字符串引用 = ""; }
  公共类 qty3p4 { 公共字符串标签 = "uniqueval62156";公共字符串值 = "";公共字符串引用 = ""; }

  公共类 qty4 { 公共字符串标签 = "uniqueval25326";公共字符串值 = "";公共字符串引用 = ""; }

}

然后我创建一个新的父对象:

StockChecklist theCurrentList = new StockChecklist();

但是如何访问嵌套对象'tag'、'value'和'reference'呢?我希望有一些简单的东西,比如 StockChecklist.qty1p1.tag = 'changedval999999999';

用 C# 可以实现这样的事情吗?

【问题讨论】:

  • 目前还不清楚为什么你有所有这些隐晦且非常规命名的嵌套类。您能否为您要实现的目标提供更多背景信息?很有可能有更好的解决方案。请注意,创建外部类的实例不会自动创建任何嵌套类的实例。
  • 你可以在这里找到答案msdn.microsoft.com/en-us/library/ms173120.aspx
  • 您可以使用 Dictionary 类而不是创建 6 个具有相同目的的类,即存储一些值
  • 该程序用于在仓库中保存物品。每个项目都有一个 id ('tag')。数量('value')和描述('reference')将被动态修改。我尝试使用带有 IDictionary 对象的关联数组,但似乎您只能有一个键和一个值,而我需要一个键('tag' - 但这可以在程序中更改)和 2 个值('value'和“描述”)

标签: c# string class nested


【解决方案1】:

您混淆了定义声明。定义嵌套类不会创建实例。此外,您定义的类看起来都使用相同的属性。所以,你应该定义一个类并声明多个实例。

您可以通过以下方式解决此问题:

C# 6.0

public class Info
{
    public string tag { get; set; }
    public string value { get; set; }
    public string reference { get; set; }

}

public class StockChecklist
{
    public Info qty1p1 { get; } = new Info { tag = "uniqueval23456", value = "", reference = "" };
    public Info qty1p2 { get; } = new Info { tag = "uniqueval3736", value = "", reference = "" };

    public Info qty2 { get; } = new Info { tag = "uniqueval97357", value = "", reference = "" };

    public Info qty3p1 { get; } = new Info { tag = "uniqueval88356", value = "", reference = "" };
    public Info qty3p2 { get; } = new Info { tag = "uniqueval62346", value = "", reference = "" };
    public Info qty3p3 { get; } = new Info { tag = "uniqueval09876", value = "", reference = "" };
    public Info qty3p4 { get; } = new Info { tag = "uniqueval62156", value = "", reference = "" };
    public Info qty4 { get; } = new Info { tag = "uniqueval25326", value = "", reference = "" };
}

在 C# 6.0 之前,您必须在构造函数中创建实例。

public class StockChecklist
{

    public StockChecklist()
    {
        qty1p1 = new Info { tag = "uniqueval23456", value = "", reference = "" };
        qty1p2 = new Info { tag = "uniqueval3736", value = "", reference = "" };

        qty2 = new Info { tag = "uniqueval97357", value = "", reference = "" };

        qty3p1 = new Info { tag = "uniqueval88356", value = "", reference = "" };
        qty3p2 = new Info { tag = "uniqueval62346", value = "", reference = "" };
        qty3p3 = new Info { tag = "uniqueval09876", value = "", reference = "" };
        qty3p4 = new Info { tag = "uniqueval62156", value = "", reference = "" };
        qty4 = new Info { tag = "uniqueval25326", value = "", reference = "" };
    }

    public Info qty1p1 { get; private set; }
    public Info qty1p2 { get; private set; }

    public Info qty2 { get; private set; }

    public Info qty3p1 { get; private set; }
    public Info qty3p2 { get; private set; }
    public Info qty3p3 { get; private set; }
    public Info qty3p4 { get; private set; }
    public Info qty4 { get; private set; }
}

注意:就像一些 cmet 已经指出的那样,在一个类中声明同一个类的 8 个实例可能指向“糟糕”的设计。你可以为它创建一个Dictionary<>


这是一个字典版本:(bonus)

public class Info
{
    public string tag { get; set; }
    public string value { get; set; }
    public string reference { get; set; }

}

public class StockChecklist
{
    private Dictionary<string, Info> _infoDict = new Dictionary<string, Info>();

    private void AddToDict(Info info)
    {
        _infoDict.Add(info.tag, info);
    }

    public StockChecklist2()
    {
        AddToDict(new Info { tag = "uniqueval23456", value = "", reference = "" });
        AddToDict(new Info { tag = "uniqueval3736", value = "", reference = "" });
        AddToDict(new Info { tag = "uniqueval97357", value = "", reference = "" });
        AddToDict(new Info { tag = "uniqueval88356", value = "", reference = "" });
        AddToDict(new Info { tag = "uniqueval62346", value = "", reference = "" });
        AddToDict(new Info { tag = "uniqueval09876", value = "", reference = "" });
        AddToDict(new Info { tag = "uniqueval62156", value = "", reference = "" });
        AddToDict(new Info { tag = "uniqueval25326", value = "", reference = "" });
    }

    public bool TryGetByTag(string tag, out Info info)
    {
        return _infoDict.TryGetValue(tag, out info);
    }

    public Info this[string tag]
    {
        get
        {
            Info info;

            if (!_infoDict.TryGetValue(tag, out info))
                return null;

            return info;
        }
    }
}

像这样使用它:(C# 6.0)

StockChecklist stock = new StockChecklist();
Info info;
if (stock.TryGetByTag("uniqueval23456", out info))
{
    Trace.WriteLine($"{info.tag} = {info.value}");
}

或者(C# 6.0)

Trace.WriteLine(stock["uniqueval88356"]?.value);

【讨论】:

  • 是的,这似乎是我出错的地方。我只需要声明一个单独的类,然后使用该类在我的另一个类中实例化对象。我错误地认为嵌套类在某种程度上是访问类中对象的答案
  • 我刚刚看了你的更新,以及不同C#版本的区别。这超出了我的要求。非常感谢!
  • 我没有意识到我也可以将自己的自定义类型与 Dictionary 一起使用!哇谢谢你!看起来我需要进一步研究
  • 请问,在第一个代码示例中,为什么要声明 {get; } 对于每个 Info 实例?
  • 我建议使用属性。由于该属性必须写入一次,因此定义 getter 将使其只读。如果您使用的是 c# 6.0 之前的版本,则必须将 setter 定义为 private。
【解决方案2】:

你应该这样做:

  public class qty1p1 { public string tag = "uniqueval23456"; public string value = ""; public string reference = ""; }
  public class qty1p2 { public string tag = "uniqueval3736"; public string value = ""; public string reference = ""; }

  public class qty2 { public string tag = "uniqueval97357"; public string value = ""; public string reference = ""; }

  public class qty3p1 { public string tag = "uniqueval88356"; public string value = ""; public string reference = ""; }
  public class qty3p2 { public string tag = "uniqueval62346"; public string value = ""; public string reference = ""; }
  public class qty3p3 { public string tag = "uniqueval09876"; public string value = ""; public string reference = ""; }
  public class qty3p4 { public string tag = "uniqueval62156"; public string value = ""; public string reference = ""; }

  public class qty4 { public string tag = "uniqueval25326"; public string value = ""; public string reference = ""; }

public class StockChecklist
{
    public qty1p1 _qty1p1;
    public qty1p2 _qty1p2;
.
.
.
}

然后你可以像这样使用它:

StockChecklist theCurrentList = new StockChecklist();
theCurrentList._qty1p1.tag = 'changedval999999999';

【讨论】:

  • 你的意思可能是theCurrentList.qty1p1.tag,不是吗?此外,您需要先在 StockCheckList 中实例化这些属性。
  • 当然可以。当您从问题中复制代码时会发生这种情况。你忘了编辑它;)
  • 仍然会遇到 NRE,因为 _qty1p1 没有实例化 :)
  • 拥有 1 个具有 Tag、Value、Reference 属性的类就足够了
【解决方案3】:

你可以这样做:

public class Parent
{

    public class child1 { public string name = "a"; public int Value = 1;}
    public class child2 { public string name = "b"; public int Value = 2;}
    public class child3 { public string name = "c"; public int Value = 3;}
    public class child4 { public string name = "d"; public int Value = 4;}
    public class child5 { public string name = "e"; public int Value = 5;}
    public child1 c1;
    public child2 c2;
    public child3 c3;
    public child4 c4;
    public child5 c5;
    public Parent() {
        this.c1 = new child1();
        this.c2 = new child2();
        this.c3 = new child3();
        this.c4 = new child4();
        this.c5 = new child5();
    }
}

class Program
{
    static void Main(string[] args)
    {

        Parent p1 = new Parent();
        Console.WriteLine(p1.c1.name);
        Console.WriteLine(p1.c2.name);
        Console.WriteLine(p1.c3.name);
        Console.WriteLine(p1.c4.name);
        Console.WriteLine(p1.c5.name);
        Console.ReadLine();

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多