问题描述
假设我有以下代码。
static class Store<T> {
public static T A;
public static T B;
public static T C;
}
public static class Store {
public static Value A = new Value(<T>(v) => Store<T>.A = v); //just an example of what I want
public static Value B = new Value(<T>(v) => Store<T>.B = v); //just an example of what I want
public static Value C = new Value(SetC<T>); //just an example of what I want
public static void SetA<T>(T value) { Store<T>.A = value; }
public static void SetB<T>(T value) { Store<T>.B = value; }
public static void SetC<T>(T value) { Store<T>.C = value; }
}
public class Value {
Action<T><T> _valueChanger; //just an example of what I want
public Value(Action<T><T> valueChanger) { //just an example of what I want
_valueChanger = valueChanger;
}
public void SetValue<T> (T value) {
_valueChanger<T>(value); //just an example of what I want
}
}
我想写入 Store.A.SetValue(42)
,以便将值保存到 Store< int> .A
。我可以写什么,而不是标记为只是我想要的一个例子的线条来实现这一点? (我想探索一个不涉及字典或类似东西的解决方案)
I want to write Store.A.SetValue(42)
so that the value is saved to Store<int>.A
. What can I write instead of the lines marked by "just an example of what I want" to make that happen? (I want to explore a solution that doesn't involve dictionaries or something similar)
重新解决问题:
我想修改类值
(定义一些字段,写一个构造函数并写入方法Value.SetValue(T value)),然后构造三个不同的变量,类型为Value(A,B, C)以这样的方式,当我调用 Store.A.SetValue(42)
值 Store< int> .A
更改为42.
Rephrasing the question:I want to modify class Value
(define some fields, write a constructor and write the method Value.SetValue(T value) ), then construct three different variables of type Value (A, B, C) in such a way that when I call Store.A.SetValue(42)
the value Store<int>.A
is changed to 42.
类的另一个变体:
static class Holder<T> {
T Value { get; set; }
}
static class Store2<T> {
public static Holder<T> A = new Holder<T>();
public static Holder<T> B = new Holder<T>();
public static Holder<T> C = new Holder<T>();
}
public static class Store2 {
public static Value A = new Value2(Store2<>.A); //just an example of what I want
public static Value B = new Value2(Store2<>.B); //passing non-specific generic expression
public static Value C = new Value3({TFree}() => Store2<TFree>.C); //just an example of what I want
}
public class Value2 { //Non-generic class!
Holder{TFree}<TFree> _holder; //just an example of what I want
public Value(Holder{TFree}<TFree> holder) { //just an example of what I want
_holder = holder;
}
public void SetValue<T> (T value) {
_holder{T}.Value = value; //just an example of what I want
}
}
public class Value3 { //Non-generic class! (Another variation)
Func{TFree}<Holder<TFree>> _holderFactory; //just an example of what I want
public Value(Func{TFree}<Holder<TFree>> holderFactory) { //just an example of what I want
_holderFactory = holderFactory;
}
public void SetValue<T> (T value) {
Holder<T> holder = _holderFactory{T}(); //just an example of what I want
holder.Value = value;
}
}
解决方案:
使用另一个问题的答案(和)。解决方案是。
Solution:An easy reflection-free and collection-free solution was found using the answers to another question ( Emulating delegates with free generic type parameters in C# and Emulating delegates with free generic type parameters in C#). The solution is Delegates to generic operations where the generic type is unknown. How to create something like that?.
推荐答案
问题证明是可以解决的。 Mike-z给了我一个几乎正确的代理 - 通用方法问题的解决方案(),我修改为一个完整的解决方案:()。
The problem turned out to be solvable. Mike-z gave me a nearly right solution for the delegate-to-generic-method problem ( Emulating delegates with free generic type parameters in C#) which I modified to be a full solution: ( Emulating delegates with free generic type parameters in C#).
解决方案这个问题也变得很容易。接口可以包含通用方法,我们可以使用接口值变量来存储通用方法的链接,而不指定具体的类型参数。以下代码使用 Store< T>
类而不进行修改,并使用 ISetter
界面和 ASetter
/ BSetter
/ CSetter
closures保存对不同通用成员的引用。 值
类将引用存储在一个 ISetter
-typed变量中,并使用通用成员 _setter
链接到一次类型参数 T
变为可用。
The solution this question becomes easy too. Interfaces can contain generic methods and we can use the interface-valued variables to store links to generic methods without specifying concrete type arguments. The following code utilizes the Store<T>
class without modifications and uses the ISetter
interface and ASetter
/BSetter
/CSetter
"closures" to hold references to different generic members. The Value
class stores the references in a ISetter
-typed variable and uses the generic member which the _setter
links to once the type argument T
becomes available.
public interface ISetter {
void SetValue<T>(T value);
}
public static class Store {
public static Value A = new Value(new ASetter());
public static Value B = new Value(new BSetter());
public static Value C = new Value(new CSetter());
class ASetter : ISetter {
public void SetValue<T>(T value) { Store<T>.A = value; }
}
class BSetter : ISetter {
public void SetValue<T>(T value) { Store<T>.B = value; }
}
class CSetter : ISetter {
public void SetValue<T>(T value) { Store<T>.C = value; }
}
}
public class Value {
ISetter _setter;
public Value(ISetter setter) {
_setter = setter;
}
public void SetValue<T> (T value) {
_setter.SetValue<T>(value);
}
}
这篇关于代表通用类型未知的通用操作。如何创建这样的东西?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!