Метод расширения C # для объекта - PullRequest
31 голосов
/ 04 февраля 2011

Является ли хорошей идеей использовать метод расширения в классе Object?

Мне было интересно, зарегистрировал ли этот метод, если вы понесли снижение производительности, так как оно будет загружено на каждый загруженный объектв контексте.

Ответы [ 6 ]

33 голосов
/ 04 февраля 2011

В дополнение к другим ответам:

не будет никакого снижения производительности, поскольку методы расширения являются функцией компилятора.Рассмотрим следующий код:

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

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

Вызов MyMethod будет фактически скомпилирован в:

MyExtensions.MyMethod(obj);
12 голосов
/ 04 февраля 2011

Производительность не будет снижена, поскольку она не привязана к каждому типу в системе, она доступна только для вызова любого типа в системе. Все, что произойдет, это то, что метод покажет на каждый единственный объект в intellisense.

Вопрос в следующем: действительно ли вам нужно , чтобы оно было на объекте, или оно может быть более конкретным. Если это должно быть на объекте, сделайте это для объекта.

3 голосов
/ 04 февраля 2011

Если вы действительно намереваетесь расширить каждый объект, то делать это правильно. Однако, если ваше расширение действительно применяется только к подмножеству объектов, оно должно применяться к наивысшему иерархическому уровню, который необходим, но не более.

Кроме того, метод будет доступен только в том случае, если импортировано ваше пространство имен.

Я расширил Object для метода, который пытается привести к указанному типу:

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

Я также перегрузил его, чтобы принять success bool (как 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 и используя конвертер), но это становится более сложным.

2 голосов
/ 04 февраля 2011

Хорошо ли использовать метод расширения в классе 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;
}
0 голосов
/ 11 мая 2018

Это старый вопрос, но я не вижу здесь ответов, которые пытаются повторно использовать существующую функцию поиска для активных объектов.Вот краткий метод расширения с необязательной перегрузкой для поиска неактивных объектов.

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 с массивом для обхода цикла для устранения генерации мусора.

0 голосов
/ 12 января 2015

В следующем примере демонстрируется используемый метод расширения.

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();
...