查找对象是否具有特定方法

时间:2014-10-15 21:56:17

标签: c# performance interface

我试图编写一个不仅易于阅读而且具有灵活性的代码。 为此,我更频繁地使用接口。例如,我没有将List作为方法的参数,而是尽可能使用IEnumerable。

但请检查此方法

public static Color MeanColor(this IEnumerable<Color> list) {
        var colors = list as Color[] ?? list.ToArray();
        if (!colors.Any()) {
            // Gray is the mean of all colors (Black+White/2)
            return Color.FromArgb(127, 127, 127);
        }

        var r = 0;
        var g = 0;
        var b = 0;
        foreach (var c in colors) {
            r += c.R;
            g += c.G;
            b += c.B;
        }

        return Color.FromArgb(r / colors.Length, g / colors.Length, b / colors.Length);
    }

因为我需要使用Length方法/属性,所以我不能只使用IEnumerable。因此,我检查它是否是一个数组,如果它不是我使用ToArray()方法将其转换为一个数组。

我尝试使用&#39;计数&#39; foreach循环中的变量,就像这个

int count = 0;
foreach (var c in colors) {
            r += c.R;
            g += c.G;
            b += c.B;
            count++;
        }

但是性能命中大于将50000元素列表转换为数组。

所以我想知道:是否可以问一个对象&#39;如果有方法&#34; X&#39 ;?是这种情况,&#34;问&#34;对象,如果它具有Count属性或GetLength()方法。

编辑:在这种情况下,蒂姆的答案确实解决了我的问题。但问题仍然存在,是否有可能要求对象具有特定的方法/属性?

2 个答案:

答案 0 :(得分:4)

您可以使用Enumerable.Count

public static Color MeanColor(this IEnumerable<Color> list) {
    int count = list.Count();
    // ...
    return Color.FromArgb(r / count, g / count, b / count);
}

请注意,如果它不是集合,这将完全执行查询,因此我使用该变量只执行一次。

答案 1 :(得分:1)

可以使用.net reflection来询问对象属性是否存在,这是代码分析对象和类的能力。在您的情况下,通过在类型上使用GetMethod方法,您可以通过检查null来查看存在与否的方法。

MethodInfo mInfo = typeof(Program).GetMethod("MethodA");
var methodExists = mInfo != null;

constructors, fields, properties, and moreGetConstructorGetFieldGetProperties,...)存在相同的原则

找到一些方法(如反射方法)更复杂,但你可以在this very site

上有一些指示