C#:使用分部类访问Dictionary



我正试图通过使用分部类以以下方式访问Dictionary。这样做的最终目的是公开这个字典,并允许不同的方法直接从中读/写

FilenameABC.cs有这样的代码,到目前为止似乎对我来说还可以:

namespace Namespace1
{
partial class ClassA
{
public class ExampleDictionary
{
private Dictionary<int, string> _dict;
public ExampleDictionary()
{
_dict = new Dictionary<int, string>();
}
}
}
}

FilenameDEF.cs有这个代码,这就是我遇到困难的地方。我不知道为什么.Add方法不起作用。在第一个例子中,我试图在创建ExampleDictionary类的实例后使用它,这似乎非常违背直觉(当然,考虑到我目前的知识水平)。在第二个例子中,我试图从一个方法内部添加元素,这就是

namespace Namespace1
{
partial class ClassA
{
ExampleDictionary instanceOfDict = new ExampleDictionary();
instanceOfDict.Add(1, "Test1"); // This does not work
public static void FunctionA()
{            
for (int i = 0; i < 10; i++)
{
string text = $"Test{i}";
instanceOfDict.Add(i, text); // This does not work as well              
}          
}
}
}

有人能帮忙吗?

静态方法FunctionA无法访问ClassA的实例成员。

FunctionA更改为非静态,或者使dictionary字段为静态。

我仍然不太清楚你想做什么。但我会尽我所能向你展示一些东西。

我接受你写的这句话:"这样做的最终目的是公开这本词典,并允许不同的方法直接从中读/写作为我的向导

部分类别问题

正如我在评论中提到的:不存在分部类。partial关键字只是表示一个类可以在多个文件中定义。类的定义规则保持不变,只是一些类成员可以在一个文件中定义,其他部分可以在其他文件中定义。

您在这里遇到的问题与partial关键字无关。

您的两个//这不起作用备注

第一个看起来像这样:

partial class ClassA
{
ExampleDictionary instanceOfDict = new ExampleDictionary();
instanceOfDict.Add(1, "Test1"); // This does not work
//other code
}

第一行声明ClassA的私有成员字段instanceOfDict并对其进行初始化。这就是它编译的原因。

第二行尝试将可运行代码(函数调用)直接放在类的顶级范围中。你不能那样做。你可以把一堆东西放在类的顶级范围(例如,字段、属性、方法、委托、枚举、内部类),但你不能把代码放在那里。

你的第二期是这样的:

public static void FunctionA()
{            
for (int i = 0; i < 10; i++)
{
string text = $"Test{i}";
instanceOfDict.Add(i, text); // This does not work as well              
}          
}

FunctionA是一种static方法。instanceOfDict是类的私有字段,未声明为静态字段。不能从静态方法引用实例到实例级别的成员(方法、属性、字段…)。阅读static关键字。

创建一个选择性公开字典的类

由于你想在类内部做一些字典工作,但要将它暴露在外部,所以我全力以赴,在<TKey, TValue>上使我的类成为泛型,这样它就可以与任何类型的Dictionaries一起使用。

我还让它实现了集合初始化模式,这样你就可以像初始化字典一样初始化类的实例。

要使用集合初始化模式,您的类必须执行以下操作:

  1. 实现IEnumerableIEnumerable<T>(T可以是任何类型,而不仅仅是您正在收集的类型-如果您不在乎,甚至可以抛出一个NotImplementedException)

  2. 包括一个看起来像public void Add (SomeType atLeastOneParameter)的方法。如果需要,可以有多个Add过载。

所以,我从这个开始(注意,它实现了IEnumerable<T>:

public partial class TestExposedDictionary<TKey, TValue> : IEnumerable<TValue>
{
private readonly Dictionary<TKey, TValue> _theDictionary = new Dictionary<TKey, TValue>();
public void Add(TKey key, TValue value)
{
_theDictionary.Add(key, value);
}
public IEnumerator<TValue> GetEnumerator()
{
foreach (var kvp in _theDictionary)
{
yield return kvp.Value;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}

这足以让一个类看起来像一个字典(你可能想添加一些方法来获取数据,等等)。但是,这取决于你(你可能想要一个索引器(在TKey上)和一个TryGetValue上)。

但是,让我们为类添加一些更随机的功能(将其放在类的顶级范围):

public int Count => _theDictionary.Count;
public IEnumerable<KeyValuePair<TKey, TValue>> GetKeyValuePairs()
{
foreach (var kvp in _theDictionary)
{
yield return kvp;
}
}

这将允许您查看字典中有多少内容,并允许您迭代dictionary集合的项(KeyValuePairs)。请随意添加更多功能。

最后,为了测试这个。。。

public static void Test()
{
var testDict = new TestExposedDictionary<int, string> {
{1, "one" },
{5, "five" },
{8, "eight" },
{10, "ten" },
{105, "hundredFive" },
};
// I can call Add in the normal way as well:
testDict.Add(300, "threeHundred");
Console.WriteLine($"TestDict Count: {testDict.Count}");
foreach (string s in testDict)
{
Console.WriteLine(s);
}
}

当我运行这个代码时,我得到:

TestDict Count: 6
one
five
eight
ten
hundredFive
threeHundred

使用部分拆分

我不知道你为什么要用partial class。通常,这样做是为了让两块代码由不同的人物角色编辑/维护(典型的原因是Visual Studio的模板/向导机制维护partial class的一侧,而程序员维护另一侧

规则非常简单,只需在两个文件中声明public partial class MyClass即可。这两个文件必须在同一个项目中(即编译到同一程序集中),并且类必须在相同的命名空间中。完成此操作后,只需在两个partial class声明中拆分(顶级作用域)部分即可。

在这种情况下,我可能会这样划分:

  • 一方面,我将提供实现声明的IEnumerator<TValue>所需的两个函数:
    • public IEnumerator<TValue> GetEnumerator()
    • IEnumerator IEnumerable.GetEnumerator()
  • 在另一边,我会把其他一切都放在一边:
    • 字典声明和初始化
    • 另一个枚举器:public IEnumerable<KeyValuePair<TKey, TValue>> GetKeyValuePairs()
    • public int Count => _theDictionary.Count;
    • public void Add(TKey key, TValue value)

最新更新