Ну, простыми словами:
Вы пытаетесь получить доступ к объекту, который не создан или в настоящее время не находится в памяти.
Итак, как это решить:
if (i == null) {
// Handle this
}
Поиск по имени означает, что некоторые фреймворки позволяют использовать FIndObjects с помощью строк, а код может выглядеть так: FindObject («ObjectName»);
Нет, вы не можете объявлять общие операторы в C #.
Операторы и наследование не очень хорошо смешиваются.
Если вы хотите, чтобы Foo + Foo возвращал Foo и Bar + Bar, чтобы вернуть панель, вам нужно будет определить один оператор для каждого класса. Но, поскольку операторы являются статическими, вы не получите преимуществ полиморфизма, потому что оператор для вызова будет решаться во время компиляции:
Foo x = new Bar();
Foo y = new Bar();
var z = x + y; // calls Foo.operator+;
Вы можете просто определить оператор в универсальном классе Foo.
Вы также можете создавать реальные общие операторы, но компилятор C # не будет их использовать.
[System.Runtime.CompilerServices.SpecialName]
public static T op_Addition<T>(T a, T b) { ... }
Вы не можете объявлять общие операторы в 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;
}
Вы также можете заинтересованы в этой краткой обзорной статье . Я наткнулся.
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);
}
Ищет то же самое, и 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.