2013-09-19 1 views
0

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

Так вопрос, когда я пытаюсь вернуть массив как это:

string[] dic_vstup = new string[] { (line) }; 
      RozhraniWSDL.InformaceOPlatciType[] dic_vystup; 
      RozhraniWSDL.rozhraniCRPDPH srv = new RozhraniWSDL.rozhraniCRPDPH(); 
      StatusType status = srv.getStatusNespolehlivyPlatce(dic_vstup, out dic_vystup); 
      string abc = status.bezVypisuUctu.ToString(); // If it is already a string, then ToString not needed 


      for (int i = 0; i < dic_vystup.Length; i++) 
      { 
       RozhraniWSDL.InformaceOPlatciType info = dic_vystup[i]; 


for (int x = 0; x <= 3; x++) 
{ 
    file2.WriteLine((((RozhraniWSDL.StandardniUcetType)(info.zverejneneUcty[x].Item)).cislo) + "-" 

     + (((RozhraniWSDL.StandardniUcetType)(info.zverejneneUcty[x].Item)).cislo) + "/" 

     + (((RozhraniWSDL.StandardniUcetType)(info.zverejneneUcty[x].Item)).kodBanky));  
}} 

я получаю следующее исключение: не удалось привести объект типа RozhraniWSDL.NestandardniUcetType к типу RozhraniWSDL.StandardniUcetType.

NestandardniUcetType содержит только один элемент - cislo

StandartníUcetType имеют 3 изделия- predcislo, cislo, kod banky

Вот изображение массива:

enter image description here

Я думал, что решение может заключаться в определении того, какой из результатов имеет вид StandartniUcetType и который NestandardniUcetType.

Я хотел бы спросить, можно ли это сделать?

Я нашел это решение более распространенным.

Спасибо за ваше время.

+0

Сообщение (контур) двух типов и объявления массива. –

ответ

2

Если массив имеет два различных типа, вы можете добавить if заявление, как это:

if (info.zverejneneUcty[x].Item is RozhraniWSDL.StandardniUcetType) { 
    ... 
} else { 
    ... 
} 

Немного лучший подход заключается в том, чтобы использовать команду as, например:

RozhraniWSDL.StandardniUcetType std = info.zverejneneUcty[x].Item as RozhraniWSDL.StandardniUcetType; 
if (std != null) { 
    ... 
} 
RozhraniWSDL.NestandardniUcetType nstd = info.zverejneneUcty[x].Item as RozhraniWSDL.NestandardniUcetType; 
if (nstd != null) { 
    ... 
} 

Наконец, очень хороший подход заключается в написании двух отдельных методов для двух типов и использовании dynamic для выполнения отправки. Чтобы сделать это, определить две функции, например:

static void WriteToFile(RozhraniWSDL.StandardniUcetType std, StreamWriter file) { 
    ... 
} 
static void WriteToFile(RozhraniWSDL.NestandardniUcetType nstd, StreamWriter file) { 
    ... 
} 

Теперь изменить цикл следующим образом:

for (int x = 0; x <= 3; x++) { 
    dynamic item = info.zverejneneUcty[x].Item; 
    WriteToFile(item, file2); // <<== Magic 
} 
+0

Я впечатлен вашими знаниями. Это очень помогло мне, спасибо. Могу ли я спросить, есть ли способ определить, сколько элементов содержится в массиве? Мне нужно изменить x <= ItemsInArray. Еще раз спасибо. – Marek

+1

@Marek 'info.zverejneneUcty.Length' должен работать. – dasblinkenlight

+0

+1 для '// << == Magic' хе-хе :) –

1

Используя метод расширения OfType над массивом отфильтрует для нужного вам типа

foreach (var item in info.zverejneneUcty.OfType<RozhraniWSDL.StandardniUcetType>()) 
{ 
    file2.WriteLine(item.predcislo + "-" + item.cislo + "-" + item.kodBanky); 
} 
1

Я бы перепроектировать типы и снять этот вопрос, а не через абстрактный класс, как это:

// I'm making up the inner types, adapt this to your code 
public abstract class UcetType 
{ 
    public virtual object predcislo { get; set; } 
    public virtual object cislo { get; set; } 
    public virtual object kodBanky { get; set; } 

    public virtual void WriteToFile(StreamWriter file) 
    { 
     // build the string and write it to the file 
     // considering all properties 
     // this acts as "default" for this type and all derived ones 
    } 
} 

public class StandardniUcetType : UcetType 
{ 
    // This will use the abstract as-is 
    // with all 3 properties and the "default" WriteToFile() method 
} 

public class NestandardniUcetType : UcetType 
{ 
    /// <summary> 
    /// Attempting to use this will throw an exception 
    /// </summary> 
    public override object predcislo 
    { 
     get { throw new NotSupportedException(); } 
     set { throw new NotSupportedException(); } 
    } 
    /// <summary> 
    /// Attempting to use this will throw an exception 
    /// </summary> 
    public override object kodBanky 
    { 
     get { throw new NotSupportedException(); } 
     set { throw new NotSupportedException(); } 
    } 

    // change the way WriteToFile behaves 
    public override void WriteToFile(StreamWriter file) 
    { 
     // build the string and write it to the file 
     // only considering 'cislo' property 
    } 
} 

// Usage example, based on question 
for (int i = 0; i < dic_vystup.Length; i++) 
{ 
    RozhraniWSDL.InformaceOPlatciType info = dic_vystup[i]; 

    // I assume "3" is the expected length of the array ? Change the for like this: 
    for (int x = 0; x <= info.zverejneneUcty.Length; x++) 
    { 
     //Delegate to the WriteToFile() method the task to build and write the line! 
     info.zverejneneUcty[x].Item.WriteToFile(file2); 
    } 
} 

Я не вижу никакой пользы в подходе dynamic. Это более читаемо и легко расширяется в будущем (нужен новый тип, просто выведите UcetType в новый класс и отмените его).

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