在不知道参数类型的情况下为方法生成随机参数值

时间:2014-05-27 10:17:51

标签: c#

我想解决什么问题?通过反射我想执行代码(运行实例方法和静态方法),我事先不知道如何定义运行方法。

假设我有一个MethodInfo我想要调用。我不知道它有什么参数,所以我做了以下。

首先我检查方法params是否有效(如果无效则不调用方法):

 private static IEnumerable<Type> GetValidMethodTypes()
    {
        var validTypes = new List<Type>();
        validTypes.AddRange(new[]
        {
            typeof (SByte),
            typeof(String[]),
            //etc...
        });

        return validTypes;
    }

然后我根据参数类型生成随机值:

 public object RandomizeParamValue(string typeName)
    {
        switch (typeName)
        {
            case "SByte":
            {
                //return randomized value
            }
            case "String[]":
            {
                //return randomized value
            }
            //etc...
        }
     }

例如,String []的随机值将是[“a”,“ab”,“ccc”]或[“aa”,“b”]。公式为:新字符串[随机大小在1到5之间],包含随机长度的随机字符串。一切都超级随机:)

问题是这只适用于我在代码中支持的类型。我可以为更多类型添加支持,但这是很多工作。我想让这更通用,但我真的不知道如何。我用谷歌搜索了但没有发现任何东西。有谁知道这种问题的解决方案/已知模式?

我可以重新制定这样的问题:我如何通过反思调用以下方法:

void SomeMethod(unknowntypeatcompiletime param);

其中unknowntypeatcompiletime可以是任何东西。

2 个答案:

答案 0 :(得分:0)

没有一种直接的方法可以使用随机发生器,它可以用于任何可能的类型。

根据您想要实现的目标,您可能会发现一些Mock和TDD框架(如Moq或AutoFixture)很有用(后者可以使用随机数据创建对象)。他们创造了嘲弄的对象,这是一个悬而未决的问题,他们可以随机化。

另一种方法是在应用程序之外的文件中使用某种值种子。该种子文件可以包含可能类型的对象图,其中一个是随机选择的。该文件可以在运行时加载,因此不需要重新编译。但是,此解决方案需要您在希望支持新类型时尽快扩展种子。

答案 1 :(得分:0)

在运行时之前支持您不知道的类型确实是不可能的。

但是,提供添加类型的动态方法非常容易。

尝试这样的事情:

public class Randomizer
{
    private Dictionary<Type, Delegate> _randoms
        = new Dictionary<Type, Delegate>();

    public void Add<T>(Func<T> generate)
    {
        _randoms.Add(typeof(T), generate);
    }

    public T RandomizeParamValue<T>()
    {
        return ((Func<T>)_randoms[typeof(T)])();
    }
}

然后你可以很容易地添加随机代表:

var rz = new Randomizer();
var rnd = new Random();
rz.Add(() => rnd.Next());
rz.Add(() => new [] { "a", "b", "c" }.ElementAt(rnd.Next(0, 3)));

现在我可以轻松调用此代码来获取随机值:

var randIntegers = rz.RandomizeParamValue<int>();
var randStrings = rz.RandomizeParamValue<string>();

很简单。如果这有帮助,请告诉我。