我正试图通过使用分部类以以下方式访问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一起使用。
我还让它实现了集合初始化模式,这样你就可以像初始化字典一样初始化类的实例。
要使用集合初始化模式,您的类必须执行以下操作:
实现
IEnumerable
或IEnumerable<T>
(T
可以是任何类型,而不仅仅是您正在收集的类型-如果您不在乎,甚至可以抛出一个NotImplementedException
)包括一个看起来像
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)