C#对象的扩展方法

时间:2011-02-04 18:12:20

标签: c# extension-methods

在Object类上使用扩展方法是个好主意吗?

我想知道是否通过注册此方法是否会导致性能损失,因为它会加载到上下文中加载的每个对象上。

6 个答案:

答案 0 :(得分:31)

除了另一个答案:

没有性能损失,因为扩展方法是编译器功能。请考虑以下代码:

public static class MyExtensions
{
    public static void MyMethod(this object) { ... }
} 

object obj = new object();
obj.MyMethod();

MyMethod的调用实际上将编译为:

MyExtensions.MyMethod(obj);

答案 1 :(得分:12)

没有性能损失,因为它没有附加到系统中的每个类型,它只能在系统中的任何类型上调用。所有将要发生的是该方法将在智能感知中的每个单个对象上显示。

问题是:你真的需要它在对象上,还是更具体。如果需要在对象上,则将其设为对象。

答案 2 :(得分:3)

如果你真的打算扩展每个对象,那么这样做是正确的。但是,如果您的扩展实际上仅适用于对象的子集,则应将其应用于必要的最高层级,但不能再应用。

此外,该方法仅在导入命名空间时可用。

我已经为尝试转换为指定类型的方法扩展了Object

public static T TryCast<T>(this object input)
{
    bool success;
    return TryCast<T>(input, out success);
}

我也重载它以接受success布尔(如TryParse那样):

public static T TryCast<T>(this object input, out bool success)
{
    success = true;
    if(input is T)
        return (T)input;
    success = false;
    return default(T);
}

我已将此扩展为尝试解析input(使用ToString并使用转换器),但这会变得更复杂。

答案 3 :(得分:2)

  

在Object类上使用扩展方法是个好主意吗?

是的,有些情况下它实际上是一个好主意。通过在Object类上使用扩展方法,没有任何性能损失。只要您不调用此方法,您的应用程序的性能就不会受到影响。

例如,考虑以下扩展方法,该方法列出给定对象的所有属性并将其转换为字典:

public static IDictionary<string, object> ObjectToDictionary(object instance)
{
    var dictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
    if (instance != null)
    {
        foreach (var descriptor in TypeDescriptor.GetProperties(instance))
        {
            object value = descriptor.GetValue(instance);
            dictionary.Add(descriptor.Name, value);
        }
    }
    return dictionary;
}

答案 4 :(得分:0)

以下示例演示了正在使用的扩展方法。

namespace NamespaceName
{
public static class CommonUtil
{
    public static string ListToString(this IList list)
    {
        StringBuilder result = new StringBuilder("");

        if (list.Count > 0)
        {
            result.Append(list[0].ToString());
            for (int i = 1; i < list.Count; i++)
                result.AppendFormat(", {0}", list[i].ToString());
        }
        return result.ToString();
    }
  }
}

以下示例演示了如何使用此方法。

var _list = DataContextORM.ExecuteQuery<string>("Select name from products").ToList();
string result = _list.ListToString();

答案 5 :(得分:0)

这是一个老问题,但我在这里没有看到任何答案,试图为活动的对象重用现有的find函数。这是一个简洁的扩展方法,带有可选的重载,用于查找非活动对象。

using System.Linq;

namespace UnityEngine {

public static class GameObjectExtensionMethods {

    public static GameObject Find(this GameObject gameObject, string name, 
        bool inactive = false) {

       if (inactive)
          return Resources.FindObjectsOfTypeAll<GameObject>().Where(
             a => a.name == name).FirstOrDefault();
       else
           return GameObject.Find(name);
    }
  }
}

如果在Update方法中使用此函数,您可以考虑使用数组进行循环遍历来更改LINQ语句,以消除垃圾生成。