暂时存储泛型

时间:2014-08-11 19:23:43

标签: c# .net generics visual-studio-2013

我想知道在这种情况下,如果有更好的做事方式而没有为那些应该是" generic"的东西创建很多自定义类。 与此有关的dynanmic可以有任何问题吗?

对于lambda版本,它会创建垃圾来引用updateMethod和值,对吗?

对于动态,除了性能略有下降,没有智能感和强打字外,还有什么不好吗?

将值和updateMethod存储为对象,以及稍后将对象强制转换回原始类型的TVal类型,会让人感觉很乱,并且会在这里和那里进行大量的投射。

public class Test
{
    dynamic Values;
    dynamic UpdateMethod;

    public void Update<TVal>(TVal[] values, Action<int, TVal> updateMethod) 
        where TVal : class
    {
        // lambda
        Parallel.For(0, values.Length, (i) => { updateMethod(i, values[i]); });

        // vs

        // dynamic
        Values = values;
        UpdateMethod = updateMethod;

        Parallel.For(0, values.Length, Work);
    }

    void Work(int i)
    {
        UpdateMethod(i, Values[i]);
    }
}

另外,为什么这项工作完全无效 Action<int, dynamic> UpdateMethod = updateMethod;

为什么我问这些问题?好奇心,总是善于扩展知识,为什么,如果好或坏 +如何搜索这个,如果有人在网上发布,我找不到任何搜索参数。

很抱歉,如果标题或问题不适合stackoverflow,我也不知道还能在哪里提问。

2 个答案:

答案 0 :(得分:1)

如果要将valies和方法存储为类字段,则更简洁的方法是使成为通用而不仅仅是方法

public class Test<TVal>
        where TVal : class
{
    TVal[] Values;
    Action<int, TVal> UpdateMethod;

    public void Update(TVal[] values, Action<int, TVal> updateMethod) 

    {
        // lambda
        Parallel.For(0, values.Length, (i) => { updateMethod(i, values[i]); });

        // OR

        Values = values;
        UpdateMethod = updateMethod;

        Parallel.For(0, values.Length, Work);
    }

    void Work(int i)
    {
        UpdateMethod(i, Values[i]);
    }
}

然而,使用lambda并没有错:

public void Update<TVal>(TVal[] values, Action<int, TVal> updateMethod) 
    where TVal : class
{
    // lambda
    Parallel.For(0, values.Length, (i) => { updateMethod(i, values[i]); });
}

我不知道你的意思&#34;制造垃圾&#34; - 如果你担心lambda会引入内存泄漏 - 在你衡量问题之前不要担心它。

答案 1 :(得分:0)

lambda方法是可行的方法。

您的其他方法存储&#34;价值观&#34;或&#34; UpdateMethod&#34;在成员变量中,这会不必要地增加这些变量的范围和生命周期。所以&#34;价值观&#34;可能不会收集垃圾,因为你的Test类在#34;更新&#34;结束后仍然坚持它。它还使代码不再是线程安全的。假设两个线程试图调用&#34;更新&#34;同时具有不同的参数。他们将各自覆盖&#34;值&#34;并且可能会调用错误的&#34; UpdateMethod。&#34;是的,动态效率较低。非常如此。

当你询问&#34;垃圾引用updateMethod和值时,我不确定你是什么意思,对吗?&#34;你担心它会创造临时工吗?如果是这样,使用dynamic将不会阻止临时值。垃圾收集使得临时工作变得非常有效。

最后的想法:你可能会觉得这是有价值的:Eric Lippert's thoughts on Enumerable.ForEach.它不是你正在做的事情,但有点类似。