问题
I am creating a C# web application using Silverlight 5 (VS 2010).
I initially created a console application which works fine and now i am adapting it into a web app.
Even in web application it is working fine for particularly set data type (say for example for int
instead of <T>
it is working fine) but when I use generic then it doesn't work. It compiles error free but it doesn't even debug the area which is set to "toggle break point". Initially the GUI was like this:
But as the control passes to the error prone part, the GUI suddenly disappears like this
And the place where I kept the break points is replaced by this
(see in left most) as a result I am not able to debug to find the problem .
Some explanation what I am trying to do: in the given code below I have a binary file and stored inside the "fileContents" which is of data type byte[]
(I am not disclosing to you the method to read that file, for now you can consider that fileContents contains the contents of a binary file inside the MainPage
class). Actually I will store the symbols (of the form 0 and 1 in binary file) and will find its frequency (by counting number of time it repeats in the file, but that has no problem so I am not writing the method for it). But this processingValue
variable in my code will be of generic type(<T>
) which I will store in "symbol"
(which is also of <T>
type (this symbol read from binary file could be one of these short
/int
/long
/UInt32
/UInt64
etc.) which I am not showing in my code).
I have a scenario like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace
{
public partial class MainPage: UserControl
{
byte[] fileContent;
public MainPage()
{
InitializeComponent();
fileContent = null; //Suppose it already contains binary fileContents
}
//I press the button in order to call the Huffman class because it's Object declared in it
public void ButtonClickEvent(object sender, RoutedEventArgs e)
{
MessageBox.Show("check0");
//Suppose i had stored contents of a file inside "fileContent" , so fileContent below contains
//contents of a binary file
//**THE LINE BELOW IS ERROR PRONE**
Huffman < uint > obj1 = new Huffman < uint > (this, fileContent, BitConverter.ToUInt32);
//This Object creation creates problem, whereas if i remove generic type (<T>), Then it works fine.
//If i don't use genrics then i do it like this : Huffman obj1 = new Huffman(this, fileContent); (Whereas <T> in Huffman class is replaced by "int" and it works fine)
MessageBox.Show("check1"); //This check box is never executed
}
}
public class Huffman < T > where T: struct,IComparable < T > ,IEquatable < T >
{
public Huffman(MainPage Object, byte[] fileContent, Func < byte[], int, T > converter)
{
MessageBox.Show("check2"); //It never executes
length = fileContent.Length;
size = Marshal.SizeOf(typeof (T));
byte[] data;
for (long position = 0; position + size < length; position += size)
{
data = fileContent; //This data conatains the filecontents now
T processingValue = converter(data, 0);
{
//I do something here with processingValue it could be int16/int32/int64/uin32/uint64 etc.
}
}
}
}
}
Is there any problem in BitConverter
function in Object Creation in MainPage class?
I am even not able to debug the Huffman class, I set the break points at starting and ending points of Huffman class but the control don't come inside and the buttons (created using XAML GUI) on the Internet Explorer disappears.
Here is my full code : (please pay attention i am reading a Binary file (any file with extension ".o"(FileName.o) canbe taken for testing my code, i read well)):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace FinalSS
{
public partial class MainPage : UserControl
{
public const int CHUNK_SIZE = 4096;
public const string UPLOAD_URI = "http://localhost:50323/FileUpload.ashx?filename={0}&append={1}";
public const string UPLOAD_DIALOG_FILTER = "All files (*.*)|*.*|Jpeg Images (*.jpg)|*.png|PNG Images (*.png)|*.png";
private Stream data;
private string fileName;
private long TotalBytes;
private long UploadedBytes;
byte[] fileContent;
public event Action simpleEvent;
public MainPage()
{
InitializeComponent();
progressBar.Visibility = Visibility.Collapsed;
textBox.Visibility = Visibility.Collapsed;
// fileContent = null;
UploadedBytes = 0;
TotalBytes = 0;
}
/* public void comboInvoke()
{
comboBox1.Items.Add("byte");
comboBox1.Items.Add("sbyte");
comboBox1.Items.Add("short");
comboBox1.Items.Add("int");
comboBox1.Items.Add("long");
} */
public void BrowseButtonClick(object sender, RoutedEventArgs e)
{ OpenFileDialog dlg = new OpenFileDialog();
dlg.Multiselect = false;
dlg.Filter = UPLOAD_DIALOG_FILTER;
bool? retVal = dlg.ShowDialog();
if (retVal != null && retVal == true)
{
progressBar.Visibility = Visibility.Visible;
textBox.Visibility = Visibility.Visible;
textBox.Text = "Uploading the file...";
data = dlg.File.OpenRead();
TotalBytes = data.Length;
UploadedBytes = 0;
fileName = dlg.File.Name;
progressBar.Maximum = TotalBytes;
UploadFileChunk();
}
}
private void UploadFileChunk()
{
textBox.Text = "Upload in progress...";
string uploadUri = "";
if (UploadedBytes == 0)
{
uploadUri = String.Format(UPLOAD_URI, fileName, 0); // Dont't append
}
else if (UploadedBytes < TotalBytes)
{
uploadUri = String.Format(UPLOAD_URI, fileName, 1); // append
}
else
{
return; // Upload finished
}
fileContent = new byte[CHUNK_SIZE];
int bytesRead = data.Read(fileContent, 0, CHUNK_SIZE);
data.Flush();
WebClient wc = new WebClient();
wc.OpenWriteCompleted += new OpenWriteCompletedEventHandler(wc_OpenWriteCompleted);
Uri u = new Uri(uploadUri);
wc.OpenWriteAsync(u, null, new object[] { fileContent, bytesRead });
UploadedBytes += fileContent.Length;
MessageBox.Show("check0");
Huffman<uint> obj1 = new Huffman<uint>(this, fileContent, BitConverter.ToUInt32);
MessageBox.Show("check1");
}
void wc_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e)
{
progressBar.Value = UploadedBytes;
if (e.Error == null)
{
object[] objArr = e.UserState as object[];
byte[] fileContent = objArr[0] as byte[];
int bytesRead = Convert.ToInt32(objArr[1]);
Stream outputStream = e.Result;
outputStream.Write(fileContent, 0, bytesRead);
outputStream.Close();
if (UploadedBytes < TotalBytes)
{
UploadFileChunk();
}
else
{
textBox.Text = fileName;
}
}
}
/// <summary>
/// ///////////////////////////////////////////////////////
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ShowButtonClick(object sender, RoutedEventArgs e)
{
if (simpleEvent != null) simpleEvent();
}
private void CompressButtonClick(object sender, RoutedEventArgs e)
{
}
private void CloseButtonClick(object sender, RoutedEventArgs e)
{
}
private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
private void textBox_TextChanged(object sender, TextChangedEventArgs e)
{
}
private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
}
private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
}
private void listBox2_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
private void TreeViewItem_Selected_1(object sender, RoutedEventArgs e)
{
}
private void TreeViewItem_Selected(object sender, RoutedEventArgs e)
{
}
}
public class Huffman<T> where T : struct, IComparable<T>, IEquatable<T>
{
long length;
int size;
byte[] data;
public class Node
{
public Node next, left, right;
public T symbol; // This symbol is of generic type.
public int freq;
public int is_processed;
}
public Node front, rear;
public Huffman(MainPage form, byte[] fileContent,Func < byte[], int, T > converter)
{
MessageBox.Show("check2");
// form.simpleEvent += () => ShowClick(form,fileContent);
length = 0;
front = null;
rear = null;
MessageBox.Show("check4");
length = fileContent.Length;
size = Marshal.SizeOf(typeof(T));
Stream stream = new MemoryStream(fileContent);
{
for (long position = 0; position + size < length; position += size)
{
data = fileContent;
T processingValue = converter(data, 0);
{
Node pt, temp;
bool is_there = false;
pt = front;
while (pt != null)
{
form.listBox1.Visibility = Visibility.Visible;
if (pt.symbol.Equals(processingValue))
{
pt.freq++;
is_there = true;
break;
}
temp = pt;
pt = pt.next;
}
if (is_there == false)
{
temp = new Node();
temp.symbol = processingValue;
temp.freq = 1;
temp.left = null;
temp.right = null;
temp.next = null;
temp.is_processed = 0;
if (front == null)
{
front = temp;
}
else
{
temp.next = front;
front = temp;
}
}
}
}
stream.Close();
}
MessageBox.Show("Yes correctly done");
merge_sort(front);
Print_tree(front, form);
}
public Node merge_sort(Node head)
{
if (head == null || head.next == null)
{
return head;
}
Node middle = getMiddle(head);
Node sHalf = middle.next;
middle.next = null;
return merge(merge_sort(head), merge_sort(sHalf));
}
public Node merge(Node a, Node b)
{
Node dummyHead, curr;
dummyHead = new Node();
curr = dummyHead;
while (a != null && b != null)
{
if (a.freq <= b.freq)
{
curr.next = a;
a = a.next;
}
else
{
curr.next = b;
b = b.next;
}
curr = curr.next;
}
curr.next = (a == null) ? b : a;
return dummyHead.next;
}
public Node getMiddle(Node head)
{
if (head == null)
{
return head;
}
Node slow, fast;
slow = fast = head;
while (fast.next != null && fast.next.next != null)
{
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
///////
public void Print_tree(Node treee,MainPage obj)
{
Node pt = treee;
while (pt != null)
{
obj.listBox1.Items.Add("Symbol :" + pt.symbol + " -" + " Frequency : " + pt.freq);
// Debug.WriteLine("Symbol :" + pt.symbol + " -" + " Frequency : " + pt.freq);
pt = pt.next;
}
}
}
}
Here is xml code :
<UserControl x:Class="FinalSS.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
d:DesignHeight="300" d:DesignWidth="400" Loaded="UserControl_Loaded">
<Grid x:Name="LayoutRoot" Background="Wheat" Visibility="Visible" Height="348" Width="681">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="37*" />
<ColumnDefinition Width="86*" />
<ColumnDefinition Width="558*" />
</Grid.ColumnDefinitions>
<sdk:TreeView SelectedItemChanged="TreeView_SelectedItemChanged" Margin="12,12,12,41" Background="wheat" Grid.ColumnSpan="3">
<sdk:TreeViewItem Header="File" Selected="TreeViewItem_Selected" >
<sdk:TreeViewItem.Items>
<sdk:TreeViewItem Selected="TreeViewItem_Selected_1">
<sdk:TreeViewItem.Header>
<StackPanel Orientation="Horizontal" >
<Button Content="Browse File" Width="76" Height="20" Click="BrowseButtonClick"></Button>
</StackPanel>
</sdk:TreeViewItem.Header>
</sdk:TreeViewItem>
<sdk:TreeViewItem Selected="TreeViewItem_Selected_1">
<sdk:TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<Button Content="Show Data" Width="75" Height="20" Click="ShowButtonClick"></Button>
</StackPanel>
</sdk:TreeViewItem.Header>
</sdk:TreeViewItem>
<sdk:TreeViewItem Selected="TreeViewItem_Selected_1">
<sdk:TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<Button Content="Compress" Width="75" Height="20" Click="CompressButtonClick"></Button>
</StackPanel>
</sdk:TreeViewItem.Header>
</sdk:TreeViewItem>
<sdk:TreeViewItem Selected="TreeViewItem_Selected_1">
<sdk:TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<Button Content="close" Width="75" Height="20" Click="CloseButtonClick" ></Button>
</StackPanel>
</sdk:TreeViewItem.Header>
</sdk:TreeViewItem>
</sdk:TreeViewItem.Items>
</sdk:TreeViewItem>
</sdk:TreeView>
<ProgressBar Name="progressBar" Height="9" HorizontalAlignment="Left" Margin="216,82,0,0" VerticalAlignment="Top" Width="139" Foreground="#FF3AB802" Grid.Column="2" Visibility="Collapsed" />
<TextBox Name="textBox" Height="23" HorizontalAlignment="Left" Margin="146,68,0,0" VerticalAlignment="Top" Width="66" Grid.Column="2" TextChanged="textBox_TextChanged" Visibility="Collapsed" />
<ListBox Height="148" HorizontalAlignment="Left" Margin="0,152,0,0" Name="listBox1" VerticalAlignment="Top" Width="197" ItemsSource="{Binding}" Visibility="Collapsed" Grid.Column="2" SelectionChanged="listBox1_SelectionChanged"></ListBox>
<ListBox Height="148" HorizontalAlignment="Right" Margin="0,154,160,0" Name="listBox2" VerticalAlignment="Top" Width="203" SelectionChanged="listBox2_SelectionChanged" Visibility="Collapsed" Grid.Column="2">
<ListBoxItem />
<ListBoxItem />
</ListBox>
<ComboBox Height="19" HorizontalAlignment="Left" Margin="13,204,0,0" Name="comboBox1" VerticalAlignment="Top" Width="104" SelectionChanged="comboBox1_SelectionChanged" Grid.ColumnSpan="2">
<ComboBoxItem />
<ComboBoxItem />
</ComboBox>
</Grid>
</UserControl>
As far as my surety is concerned this problem is due to BitConverter in huffman constructor invoke the function Func converter creates problem. I guess i need to use Func converter some other way And big thanks for helping me.
回答1:
I could be wrong about this but...
I don't know think you can do what you are doing without adding more code -
<T>
is really a placeholder for a datatype, used by the compiler to create a class that works with that type. The class/function is created by the compiler when you specify a variable with that class type.
It sounds to me like you are trying to create this type at runtime and then call this function. By doing this you have not allowed the compiler to create a method/class to support your variable type.
You may need to declare a class for each type in some dummy file so that the compiler will generate classes for those types.
Take a look at this article for some more info: http://www.cs.umd.edu/class/fall2002/cmsc214/Projects/P2/proj2.temp.html
来源:https://stackoverflow.com/questions/22899744/issues-with-generics-using-silverlight