Difference between System.Collections.Generic.List <T> .ToArray () and System.Linq.Enumerable.ToArray <T> ()?

I recently had a problem with a specific web method that I use:

void CheckGfiHelpdesks(string ticket, GfiCheck[] newHelpdeskChecks, GfiCheck[] otherChecks)

I called this method with this code:

List<GfiCheck> newFailedChecks = new List<GfiCheck>();

List<GfiCheck> otherFailedChecks = new List<GfiCheck>();

//do some work, create new GfiCheck items, fill the lists

Webclient.CheckGfiHelpdesks(Ticket, newFailedChecks.ToArray(), otherFailedChecks.ToArray());

newFailedChecks and otherFailedChecks - List. This works great when the method worked in IIS as a SOAP service.

However, after I copied the same method to the WCF service, the call threw a 400 bad request exception.

In the end, I realized that .ToArray () is really a problem. It:

Webclient.CheckGfiHelpdesks(Ticket, newFailedChecks.ToArray<GfiCheck>(), otherFailedChecks.ToArray<GfiCheck>());

i.e. using System.Linq.Enumerable.ToArray<T>()instead System.Collections.Generic.List<T>.ToArray(), finally solved the problem and the exception disappeared.

What is the explanation for this difference? An array is an array, but apparently not?

Exact exception:

System.ServiceModel.ProtocolException

: (400) .

StackTrace:

:

System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse( HttpWebRequest, HttpWebResponse, HttpChannelFactory factory, WebExceptionException, ChannelBinding)

System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(- TimeSpan)

System.ServiceModel.Channels.RequestChannel.Request( , - TimeSpan)

System.ServiceModel.Dispatcher.RequestChannelBinder.Request( , - TimeSpan)

System.ServiceModel.Channels.ServiceChannel.Call( String, Boolean oneway, ProxyOperationRuntime, Object [] ins, Object [] outs, - TimeSpan)

in System.ServiceModel.Channels.ServiceChannelProxy.InvokeService (IMethodCallMessageCall, ProxyOperationRuntime method)

in System.ServiceModel.Channels.ServiceChannelProxy.Invoke (message with message)

<P →

Exception thrown at [0]:

in System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage (IMessage reqMsg, IMessage retMsg)

in System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (MessageData & msgData, type Int32)

in MonitoringService.BL.CentronService.ICentronService.CheckGfiHelpdesks (String ticket, GfiCheck [] newHelpdeskChecks, GfiCheck [] otherChecks)

MonitoringService.BL.CentronService.CentronServiceClient.CheckGfiHelpdesks(String ticket, GfiCheck [] newHelpdeskChecks, GfiCheck [] otherChecks) C:\Users\sohrm\documents\visual studio 2010\Projects\MonitoringService\MonitoringService.BL\Service \CentronService\Reference.cs: Zeile 5368.

MonitoringService.BL.ConnectorBL.CheckHelpdesks( List`1) C:\Users\sohrm\documents\visual studio 2010\Projects\MonitoringService\MonitoringService.BL\ConnectorBL.cs: Zeile 120.

MonitoringService.WinForm.MainForm.LoadChecks() C:\Users\sohrm\documents\visual studio 2010\Projects\MonitoringService\MonitoringService.Client\MainForm.cs: Zeile 124.

MonitoringService.WinForm.MainForm.btnLoad_Click ( , EventArgs e) C:\Users\sohrm\documents\visual studio 2010\Projects\MonitoringService\MonitoringService.Client\MainForm.cs: Zeile 114.

System.Windows.Forms.Control.OnClick(EventArgs e)

DevExpress.XtraEditors.BaseButton.OnClick(EventArgs e)

DevExpress.XtraEditors.BaseButton.OnMouseUp(MouseEventArgs e)

System.Windows.Forms.Control.WmMouseUp(Message & m, MouseButtons, Int32)

System.Windows.Forms.Control.WndProc(Message & m)

DevExpress.Utils.Controls.ControlBase.WndProc(Message & m)

DevExpress.XtraEditors.BaseControl.WndProc(Message & msg)

System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message & m)

System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message & m)

System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG & msg)

System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32, Int32 pvLoopData)

System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner( Int32, ApplicationContext)

System.Windows.Forms.Application.ThreadContext.RunMessageLoop( Int32, ApplicationContext)

System.Windows.Forms.Application.Run(Form mainForm)

MonitoringService.WinForm.Program.Main() C:\Users\sohrm\documents\visual studio 2010\Projects\MonitoringService\MonitoringService.Client\Program.cs: Zeile 22.

System.AppDomain._nExecuteAssembly ( RuntimeAssembly, String [] args)

System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String [] args)

Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()

System.Threading.ThreadHelper.ThreadStart_Context ( )

System.Threading.ExecutionContext.Run(ExecutionContext executeContext, ContextCallback, , ignoreSyncCtx)

System.Threading.ExecutionContext.Run(ExecutionContext executeContext, ContextCallback, )

System.Threading.ThreadHelper.ThreadStart()

+3
1

System.Collections.Generic.List<T>.ToArray() System.Linq.Enumerable.ToArray<T>() . , :

System.Collections.Generic.List<T> :

public T[] ToArray()
{
    T[] destinationArray = new T[this._size];
    Array.Copy(this._items, 0, destinationArray, 0, this._size);
    return destinationArray;
}

System.Linq.Enumerable , :

public static TSource[] ToArray<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)    
        throw Error.ArgumentNull("source");

    Buffer<TSource> buffer = new Buffer<TSource>(source);
    return buffer.ToArray();
}

? List<T> ICollection<T>, CopyTo List<T>:

internal Buffer(IEnumerable<TElement> source)
{
   TElement[] array = null;
   ICollection<TElement> is2 = source as ICollection<TElement>;
   length = is2.Count;
   if (length > 0)
   {
       array = new TElement[length];
       // implemented as Array.Copy(this._items, 0, array, 0, this._size);
       is2.CopyTo(array, 0);
   }

   this.items = array;
   this.count = length;
}

, CopyTo, , ToArray. System.Linq.Enumerable - , , , :

internal TElement[] ToArray()
{
   if (this.count == 0)        
       return new TElement[0];

   if (this.items.Length == this.count)        
       return this.items;

   TElement[] destinationArray = new TElement[this.count];
   Array.Copy(this.items, 0, destinationArray, 0, this.count);
   return destinationArray;
}

, Array.Copy. Enumerable . ToArray, List.

+1

All Articles