您好我正在尝试重新命名名为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
这是阵列的图像:
我认为解决方案可能是确定哪个结果属于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
}
答案 1 :(得分:1)
在数组上使用OfType扩展方法将过滤所需的类型
foreach (var item in info.zverejneneUcty.OfType<RozhraniWSDL.StandardniUcetType>())
{
file2.WriteLine(item.predcislo + "-" + item.cislo + "-" + item.kodBanky);
}
答案 2 :(得分: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
并重写)。