2015-05-14 2 views
2

У меня есть следующие два класса. Адреса содержат список адресов. Метод GetMailingAddress будет сканировать через AddressList для поиска определенного типа адреса.Доступ к переменной в объекте, содержащемся в другом объекте, когда дочерний объект имеет значение null

Class Addresses 
{ 
    public List<Address> AddressList {get; set;} 

    public Address MailingAddress {get { return GetMailingAddress();} 
} 

Class Address 
{ 
    public Int? ID {get; set;} 
} 

Чтобы получить доступ к идентификатор MailingAddress I введите следующее:

Addresses obj = new Addresses(); 
int? I = obj.MailingAddress.ID 

Проблема заключается в том MailingAddress может возвращать нуль. Если это произойдет, вызов завершится неудачно, поскольку он ссылается на ID через нулевой объект. В этом случае я хотел бы вернуть значение null.

Чтобы обойти эту проблему, я использую этот код:

if(obj.MailingAddress == null) 
{ 
    I? = null; 
} 
else 
{ 
    I? = obj.MailingAddress.ID; 
} 

Есть ли способ вызова obj.MailingAddress.ID и возвращать нулевое значение, если MailingAddress является недействительным, не делать выше Если заявление.

Я мог бы также создать дополнительный метод/свойство внутри класса адресов, как это, но я снова вижу это как работа вокруг, а не чистое решение:

public int? MailingAddressID 
{ 
    if(GetMailingAddress == null) 
    { 
     return null; 
    } 
    else 
    { 
     return GetMailingAddress.ID; 
    } 
} 
+0

Вы будете любить C# 6, то ... вы можете сделать 'вар я = OBJ .MailingAddress .id;' и вы получите нужное значение. см. https://dotnetfiddle.net/THfoBi –

ответ

2

Прежде всего int это структура, и вы должны использовать ? или Nullable<int> за то, что обнуляемым, а затем:

int? myInt = obj.MailingAddress == null ? (int?)null : (int?)obj.MailingAddress.Id; 

Но, в C# 6 вы можете использовать ? оператор, который иногда называют Safe Navigation Operator:

int? myInt = obj?.MailingAddress?.Id; 

В качестве дополнительной записке, вы можете использовать Null Object Pattern. Вы можете изучить его с here и использовать этот шаблон также. Использование шаблона Null Object упрощает код и делает его менее подверженным ошибкам.

+0

Да. Это было для меня большим визитом. –

+0

Отличный ответ. Я пытался это сделать, но просто не мог заставить его работать. Не могу дождаться, пока C# 6. obj? .obj? .id очень приятно. –

+0

@SimonDarlow Рад, что это помогло. Удачи. –

0

Вот глупая реализация C# 6 Null Размножение синтаксиса в C# 5:

using System; 
using System.Diagnostics; 

public class Program 
{ 
    public static void Main() 
    { 
     var foo = new Foo { Bar = new Bar { Baz = "Hello" } }; 
     var foo1 = new Foo(); 

     var i = foo._(_=>_.Bar)._(_=>_.Baz);   //equivalent to foo?.Bar?.Baz in C# 6  
     Console.WriteLine("i is '{0}'", i);    //should be 'Hello' 

     var j = foo1._(_=>_.Bar)._(_=>_.Baz);   //equivalent to foo1?.Bar?.Baz in C# 6  
     Console.WriteLine("j is '{0}'",j);    //should be '' since j is null, but shouldn't throw exception either. 

     Console.WriteLine("js is null? {0}", j == null); 

    } 
} 

public class Foo 
{ 
    public Bar Bar { get; set; } 
} 

public class Bar 
{ 
    public string Baz { get; set; } 
} 

public static class ObjectExtension 
{ 
    //Probably not a good idea to name your method _, but it's the shortest one I can find, I wish it could be _?, but can't :(
    public static K _<T, K>(this T o, Func<T, K> f) 
    { 
     try 
     { 
      var z = f(o); 
      return z;   
     } 
     catch(NullReferenceException nex) 
     { 
      Trace.TraceError(nex.ToString()); 
      return default(K); 
     } 

    } 
} 

В основном я хочу сделать foo?.Bar?.Baz, но поскольку синтаксис не поддерживается, метод расширения, Func<..> и общие для спасения ...

Таким образом, вам не нужно менять свой объект на нулевую версию, но вам нужно указать их тип в вызове метода расширения _. foo._(_=>_.Bar)._(_=>_.Baz) выглядит немного странно, но довольно лаконична :)

Живой пример на:? https://dotnetfiddle.net/9R8bku

+0

Слишком сумасшедший для меня. Мои знания C# не могут справиться :) –

+0

Я сказал, что это CRAZY путь, LOL –

Смежные вопросы