C # Множественные типовые параметры для перегрузки оператора [дубликат]

Ну, простыми словами:

Вы пытаетесь получить доступ к объекту, который не создан или в настоящее время не находится в памяти.

Итак, как это решить:

  1. Отладить и отпустить отладчик ... Он сразу приведет вас к переменной, которая сломана ... Теперь ваша задача - просто исправить это. Используя новое ключевое слово в соответствующем месте.
  2. Если это вызвано некоторыми командами базы данных, потому что объект отсутствует, все, что вам нужно сделать, это выполнить нулевую проверку и обработать его:
    if (i == null) {
        // Handle this
    }
    
  3. Самый сложный. если GC уже собрал объект ... Это обычно происходит, если вы пытаетесь найти объект, используя строки ... То есть, найдя его по имени объекта, может случиться, что GC, возможно, уже очистил его ... Это трудно найти и станет проблемой. Лучшим способом решения этой проблемы является выполнение нулевых проверок везде, где это необходимо в процессе разработки. Это сэкономит вам много времени.

Поиск по имени означает, что некоторые фреймворки позволяют использовать FIndObjects с помощью строк, а код может выглядеть так: FindObject («ObjectName»);

20
задан Shirik 6 May 2011 в 01:23
поделиться

5 ответов

Нет, вы не можете объявлять общие операторы в C #.

Операторы и наследование не очень хорошо смешиваются.

Если вы хотите, чтобы Foo + Foo возвращал Foo и Bar + Bar, чтобы вернуть панель, вам нужно будет определить один оператор для каждого класса. Но, поскольку операторы являются статическими, вы не получите преимуществ полиморфизма, потому что оператор для вызова будет решаться во время компиляции:

Foo x = new Bar();
Foo y = new Bar();
var z = x + y; // calls Foo.operator+;
17
ответ дан R. Martinho Fernandes 28 August 2018 в 00:18
поделиться

Вы можете просто определить оператор в универсальном классе Foo.

Вы также можете создавать реальные общие операторы, но компилятор C # не будет их использовать.

[System.Runtime.CompilerServices.SpecialName]
public static T op_Addition<T>(T a, T b) { ... }
3
ответ дан Ark-kun 28 August 2018 в 00:18
поделиться

Вы не можете объявлять общие операторы в C # - я не уверен в рассуждениях, но предполагаю, что это полезность и усилия для команды внедрения (я считаю, что здесь может быть сообщение с Джоном Скитом, обсуждающим это, или, возможно, на его блог, когда он обсуждал вещи, которые он хотел бы видеть на C #).

Действительно, вы даже не можете использовать операторы с дженериками в C #.

Это потому что дженерики должны быть применимы для всех возможных типов, которые могут быть предоставлены. Вот почему вы должны использовать общий тип для классов, когда хотите использовать ==, как показано ниже:

void IsEqual<T>(T x, T y) where T : class
{
    return x == y;
}

К сожалению, вы не можете сделать:

void Add<T>(T x, T y)  where T : operator +
{
    return x + y;
}

Вы также можете заинтересованы в этой краткой обзорной статье . Я наткнулся.

1
ответ дан Matt Mitchell 28 August 2018 в 00:18
поделиться

http://www.yoda.arachsys.com/csharp/genericoperators.html

static T Add<T>(T a, T b) {
    //TODO: re-use delegate!
    // declare the parameters
    ParameterExpression paramA = Expression.Parameter(typeof(T), "a"),
        paramB = Expression.Parameter(typeof(T), "b");
    // add the parameters together
    BinaryExpression body = Expression.Add(paramA, paramB);
    // compile it
    Func<T, T, T> add = Expression.Lambda<Func<T, T, T>>(body, paramA, paramB).Compile();
    // call it
    return add(a,b);       
}
5
ответ дан Rakoo 28 August 2018 в 00:18
поделиться

Ищет то же самое, и google привел меня сюда ... Я был не слишком доволен принятым ответом и искал обходной путь.

Мне удалось реализовать это с помощью дженериков. Вот класс Foo и Bar:

    class Foo
    {
        private int value;

        public Foo(int x)
        {
            value = x;
        }
        public virtual int getVal()
        {
            return value;
        }
    }

    class Bar : Foo
    {
        private int derivedValue;

        public Bar(int x):base(x) 
        {
            derivedValue = x;
        }
        public override int getVal()
        {
            return derivedValue;
        }
    }

Тогда общий класс, содержащий операторы, но ограниченный типом Foo и полученный из Foo:

    class GenericOp<T> where T : Foo
    {
        private T value;

        public GenericOp(T x)
        {
            value = x;
        }
        public static Foo operator +(GenericOp<T> a, GenericOp<T> b) 
        {
            return new Foo(a.value.getVal() + b.value.getVal());
        }
    }

Некоторое использование кода, показывающего вы всегда возвращаетесь к Foo, а также не допускаете смешивания типов:

Foo f1 = new Foo(1);
Foo f2 = new Foo(2);
Bar b1 = new Bar(10);
Bar b2 = new Bar(20);

GenericOp<Foo> left = new GenericOp<Foo>(f1);
GenericOp<Foo> right = new GenericOp<Foo>(f2);
Foo res = left + right;

GenericOp<Bar> left1 = new GenericOp<Bar>(b1);
GenericOp<Bar> right1 = new GenericOp<Bar>(b2);
Foo res1 = left1 + right1;

GenericOp<Foo> left2 = new GenericOp<Foo>(f1);
GenericOp<Bar> right2 = new GenericOp<Bar>(b1);
//Foo res2 = left2 + right2; //this fails and rightfully so.
0
ответ дан tomatoRadar 28 August 2018 в 00:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: