代表通用类型未知的通用操作。如何创建这样的东西? [英] Delegates to generic operations where the generic type is unknown. How to create something like that?

查看:103
本文介绍了代表通用类型未知的通用操作。如何创建这样的东西?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下代码。

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; 
    }
}

解决方案:
使用另一个问题的答案(使用C#中的免费通用类型参数模拟代理使用C#中的免费通用类型参数模拟代理)。解决方案是泛型类型未知的通用操作的代理。如何创建这样的东西?

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给了我一个几乎正确的代理 - 通用方法问题的解决方案(使用C#中的免费通用类型参数模拟代理),我修改为一个完整的解决方案:(使用C#中的免费通用类型参数模拟代理)。

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);
    }
}

这篇关于代表通用类型未知的通用操作。如何创建这样的东西?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆