英文:
Dictionary/Collection of generic Delegates
问题
我想要拥有一组通用委托,每个委托都与不同的字符串键关联(类似于 Dictionary<string, delegate<T>>
)。这些委托接受 T
并返回 T
,这意味着返回类型与输入类型相同,有点像函数式的 map
。这意味着每个单独函数的类型在编译时是已知的。我看不到为什么这不可能实现,但我还没有找到实现的方法。
我看到的主要解决方案是将 T
设为 object
,然后每次都进行强制类型转换,但这很麻烦。另一个选择是使用动态类型,但这会损害类型安全性,并可能在长期内带来问题。还有可能实现一个自定义集合,但我不确定如何实现。
编辑:我想要一个通用的键值对,其中 T
对于每个键/对都是不同的类型。
英文:
I have want to have a collection of generic delegates, each tied to a different string key (something like a Dictionary<string, delegate<T>>
). The delegates take in T
and return T
, meaning that the return type is the same as the input type, kind of like functional map
. This means the type for each individual function is known at compile time. I see no reason why this shouldn't be possible but I haven't found a way to do it.
The main solutions I've seen are to make T
an object
and then cast it each time, but that's a hassle. Another option is to use dynamic, but that undermines type safety and might bring problems in the long run. There's also the possibility to implement a custom collection, but I'm not sure as to how.
Edit: I want a generic key-value pair where T
is a different type for each key/pair.
答案1
得分: 1
你可以隐藏存储的细节,并在自定义类中提供自己的方法来设置和获取委托:
public class DelegateDictionary
{
private Dictionary<string, object> _entries = new Dictionary<string, object>();
public void Add<T>(string key, Func<T, T> modifier)
{
_entries.Add(key, modifier);
}
public Func<T, T> Get<T>(string key)
{
return _entries[key] as Func<T, T>;
}
}
用法:
var dictionary = new DelegateDictionary();
dictionary.Add<string>("NameLowerCase", (name) => name.ToLower());
dictionary.Add<int>("AgeIncreaseByFive", (value) => value + 5);
var lowerCasedName = dictionary.Get<string>("NameLowerCase").Invoke("JUAN");
var numberIncreasedByFive = dictionary.Get<int>("AgeIncreaseByFive").Invoke(5);
Console.WriteLine($"JUAN => {lowerCasedName}");
Console.WriteLine($"5 => {numberIncreasedByFive}");
输出:
JUAN => juan
5 => 10
这只是一个过于简化的示例,但足以帮助你入门。
尽管如此,当我看到这样的代码时,通常意味着有必要退后一步重新考虑为什么需要这样做。
英文:
You can hide the details of storage and provide your own methods to set and get the delegates in a custom class:
public class DelegateDictionary
{
private Dictionary<string, object> _entries = new Dictionary<string, object>();
public void Add<T>(string key, Func<T, T> modifier)
{
_entries.Add(key, modifier);
}
public Func<T, T> Get<T>(string key)
{
return _entries[key] as Func<T, T>;
}
}
Usage:
var dictionary = new DelegateDictionary();
dictionary.Add<string>("NameLowerCase", (name) => name.ToLower());
dictionary.Add<int>("AgeIncreaseByFive", (value) => value + 5);
var lowerCasedName = dictionary.Get<string>("NameLowerCase").Invoke("JUAN");
var numberIncreasedByFive = dictionary.Get<int>("AgeIncreaseByFive").Invoke(5);
Console.WriteLine($"JUAN => {lowerCasedName}");
Console.WriteLine($"5 => {numberIncreasedByFive}");
Output:
JUAN => juan
5 => 10
This is an overly simplified example but it should be enough to get you going.
All this being said, when I see something like this, it's usually a code smell worth taking a step back and rethinking why you need this in the first place.
答案2
得分: 0
我不确定这是可能的。泛型的整个要点是,当 T 在上下文中使用时,它在整个上下文中是相同的类型。通过将 T 作为字典的值类型的一部分,您将所有的值都链接到相同的上下文中,因此 T 的类型也是相同的。
英文:
I'm not sure this is possible. The whole point of generics is that when T is used in a context it is the same type for the whole of that context. By using T as part of the value type for the dictionary, you are linking all of the values into the same context, and thus a single type for T.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论