如何为多个类添加扩展方法?

时间:2016-07-19 09:50:48

标签: c# reflection

我有大约1000个课程,我需要计算其中的属性数量。我有以下代码:

    public static int NumberOfProperties()
    {
        Type type = typeof(C507);
        return type.GetProperties().Count();
    }

我可以将其复制并粘贴到每个更改typeof参数的类中,但这看起来有点单调乏味。

有没有提出扩展方法来执行此操作只需执行var nop = C507.NumberOfProperties();

8 个答案:

答案 0 :(得分:44)

只需添加答案,建议object的完整性扩展名:您还可以考虑仅针对Type实施扩展程序:

public static int GetPropertyCount(this Type t)
{
    return t.GetProperties().Length;
}

并像这样使用它:

typeof(C507).GetPropertyCount();

优点是您可以直接从类型中获取属性数量,而不必先创建实例。

答案 1 :(得分:28)

因此,您可以编写使用对象的扩展方法或使用类型的扩展方法。

public static class ObjectExtensions
{
    public static int GetNumberOfProperties(this object value)
    {
        return value.GetType().GetProperties().Count();
    }

    public static int GetNumberOfProperties(this Type value)
    {
        return value.GetProperties().Count();
    }
}

用法:

new C507().GetNumberOfProperties();
typeof(C507).GetNumberOfProperties();

但是,您明确说明了两件事

  

我可以将其复制并粘贴到每个更改typeof

的类中      

我有大约1000个课程

您可能不想实例化1000个类或复制并粘贴typeof() 1000次

在这种情况下,您需要从大会中读取它们。

类似于:

typeof(SomeClass).Assembly.GetTypes().Select(x => new
  {
       x.Name, 
       PropertyCount = x.GetType().GetProperties().Count()
  });

SomeClass是所有类所在的类(并不重要)。

我只是简单地将它们选择到一个匿名对象中,该对象包含Types名称和属性计数。

此:

typeof(SomeClass).Assembly

只是一种方便的方式来获得组装。还有其他方法。

Assembly.GetAssembly(typeof(Program)).GetTypes()
Assembly.GetCallingAssembly().GetTypes()
Assembly.Load("Some Assemble Ref").GetTypes()

您可以使用找到的类型执行各种操作。如果您选择Type本身,则可以稍后使用Activator.CreateInstance实例化它(如果它具有无参数构造器)。您也可以使用反射自动填充属性。

答案 2 :(得分:22)

不可能像你想象的那样拥有静态扩展方法。话虽这么说,可以在helper类中创建一个泛型方法,如下所示。

public static int NumberOfProperties<T>()
{
    Type type = typeof(T);
    return type.GetProperties().Count();
}

如果类型为SomeType,则可以将其称为int n = NumberOfProperties<SomeType>()

答案 3 :(得分:9)

您可以在object上创建一个扩展方法,如下所示:

public static int PropertyCount(this object thing)
{
    return thing.GetType().GetProperties().Count();
}

并在你喜欢的任何物体上使用它:

var x = "some string";
var numProps = x.PropertyCount();

答案 4 :(得分:6)

如果您想在object上使用扩展方法:

public static ObjectExtensions
{
    public static int NumberOfProperties(this object value)
    {
        if (null == value)
          throw new ArgumentNullException("value"); // or return 0

        // Length: no need in Linq here
        return value.GetType().GetProperties().Length;
    }
}

...

C507 myObj = new C507();

// How many properties does myObj instance have?
int propCount = myObj.NumberOfProperties(); 

如果您想在Type上使用extesnion方法:

   public static TypeExtensions
    {
        public static int NumberOfProperties(this Type value)
        {
            if (null == value)
              throw new ArgumentNullException("value"); // or return 0

            // Length: no need in Linq here
            return value.GetProperties().Length;
        }
    }

    ...


    // How many properties does C507 type have?
    int propCount = typeof(C507).NumberOfProperties(); 

答案 5 :(得分:1)

有几种方法可以做同样的事情。

您可以将Type作为参数传递给方法:

public static class Helper {
    public static int NumberOfProperties(Type type)
    {
        return type.GetProperties().Count();
    }
}

你会这样称呼:

// Imagine you have a class called MyClass
var result = Helper.NumberOfProperties(typeof(MyClass));

您使用C#中的通用系统来使语法更清晰。这看起来像这样:

public static class Helper {
    // Notice the argument was removed and 
    // the use of the "generic" syntax <T>
    public static int NumberOfProperties<T>()
    {
        var type = typeof(T);
        return type.GetProperties().Count();
    }
}

你会这样称呼它:

var result = Helper.NumberOfProperties<MyClass>();

您还可以使用“扩展程序”,它允许您将其称为属于您的类的方法。

public static class Helper {
    // notice the `this` keyword before the parameter 
    // this is what tells C# that this is an extension method
    public static int NumberOfProperties<T>(this T @this)
    {
        var type = typeof(T);
        return type.GetProperties().Count();
    }
}

这将允许您调用如下方法:

 var instance = new MyClass();
 var result = instance.NumberOfProperties();

在这个例子中,我使用了通用语法,以便它适用于任何类型的对象。如果要将其限制为仅从特定接口或基类继承的对象,则只需将其从使用通用语法更改为使用基类/接口。像这样:

public static class Helper {
    // notice the type got changed from a generic <T>
    // to specifying the exact class you want to "extend"
    public static int NumberOfProperties(this MyBaseClass @this)
    {
        var type = typeof(T);
        return type.GetProperties().Count();
    }
}

正如@rené-vogt所提到的,您还可以创建扩展方法,以便它扩展类型Type。请参阅此主题中的答案:https://stackoverflow.com/a/38455233/984780

答案 6 :(得分:0)

您可以制作适用于所有类型的通用扩展方法:

public static int PropertyCount<T>(this T obj)
{
    return typeof(T).GetProperties().Length;
}

这将适用于所有类型,包括应用于对象的值类型(IE结构)。感谢piedar指出我的错误,应用于对象仍然添加这个扩展方法来赋值类型。

答案 7 :(得分:0)

如果您的分类可以实现接口,那么您可以扩展该接口。

public interface IExtensible {
}

class C507 : IExtensible {

}

public static int NumberOfProperties(this IExtensible extensible)
{
    Type type = extensible.GetType();
    return type.GetProperties().Count();
}

话虽如此,拥有数百个(生成的)类似乎是一个糟糕的解决方案。