C#使用Dictionary和Func创建一个带有ctor参数的新实例



我想知道是否可以使用字典为给定类型的解析器创建一个类型的新实例,其中新类型具有构造函数args。本质上是一种工厂方法。

尽管我希望有一种更干净的方法,但我还是有一些可行的方法。我在Java中遇到了这个问题,并认为这在C#中很容易——也许不是!

因此,它是基于给定的字典:

Dictionary<Type, Func<ToResolve, Resolved>>

其具有用于给定类型的解析器CCD_ 2。我想从ToResolve映射,以解决将ToResolve字段传递给ToResolve构造函数参数的问题。CCD_ 3和CCD_。ToResolve in,ToResolve out。

因此,工作场景是:

Dictionary<Type, Func<ToResolve, Resolved>> map = new Dictionary<Type, Func<ToResolve, Resolved>>
{
{
typeof(ToResolve1), r =>
{
var tr = (ToResolve1) r;
return new Resolved1(tr.x);
}
},
{
typeof(ToResolve2), r =>
{
var tr = (ToResolve2) r;
return new Resolved2(tr.x);
}
}
};

这可以称为:

var toResolve1 = new ToResolve1(100);
var resolved1 = map[toResolve1.GetType()];
var toResolve2 = new ToResolve2("some string");
var resolved2 = map[toResolve2.GetType()];

简单的类声明为:

public abstract class Resolved { }
public class Resolved1 : Resolved
{
public readonly int x;
public Resolved1(int x) => this.x = x;
}
public class Resolved2 : Resolved
{
public readonly string x;
public Resolved2(string x) => this.x = x;
}
public abstract class ToResolve { }
public class ToResolve1 : ToResolve
{
public readonly int x;
public ToResolve1(int x) => this.x = x;
}
public class ToResolve2 : ToResolve
{
public readonly string x;
public ToResolve2(string x) => this.x = x;
}

有更简洁的方法吗?理想情况下,不必将lambda封装在几行上并使用显式强制转换。

并且不使用AutoMapper

我相信你可以做你想做的事情,让你的字典保持原样,但添加单独的方法来添加条目,比如:

static class Resolver {
private static readonly Dictionary<Type, Func<ToResolve, Resolved>> _map = new Dictionary<Type, Func<ToResolve, Resolved>>();
static Resolver() {
Add((ToResolve1 tr) => new Resolved1(tr.x));
Add((ToResolve2 tr) => new Resolved2(tr.x));
}
private static void Add<TToResolve, TResolved>(Func<TToResolve, TResolved> func) where TToResolve : ToResolve where TResolved : Resolved {
_map[typeof(TToResolve)] = x => func((TToResolve) x);
}
// the only public interface, non-generic
public static Resolved Resolve(ToResolve x) {
return _map[x.GetType()](x);
}
}

看起来您只需要一堆重载方法,不确定这是您想要的简洁方法吗?

public static class Resolver
{
public static Resolved1 Resolve(ToResolve1 r) => new Resolved1(r.x);
public static Resolved2 Resolve(ToResolve2 r) => new Resolved2(r.x);
}
var resolved1 = Resolver.Resolve(new ToResolve1(100));
var resolved2 = Resolver.Resolve(new ToResolve2("some string"));

字典不支持泛型值,但是,您可以编写自己的自定义字典:

class ResolverDictionary
{
static class Resolver<T> where T : ToResolve
{
public static Func<T, Resolved> Instance;
}

public ResolverDictionary Add<T>(Func<T, Resolved> resolver) where T : ToResolve
{
Resolver<T>.Instance = resolver;
return this;
}

public Func<T, Resolved> Get<T>() where T : ToResolve
{
return Resolver<T>.Instance;
}
}

可按如下方式使用:

var dictionary = new ResolverDictionary()
.Add((ToResolve1 r) => new Resolved1(r.x))
.Add((ToResolve2 r) => new Resolved2(r.x));

var resolver1 = dictionary.Get<ToResolve1>();
var resolved1 = resolver1(new ToResolve1(100));

相关内容

最新更新