Из-за бага иногда не удаётся спрятать программно asp:LinkButton через свойство Visible. Можно спрятать через добавление стиля 'display: none'.
this.LinkButton.Style.Add("display", "none");
this.LinkButton.Style.Add("display", "none");
class Contact
{
public string Name { get; set; }
public int YearofBirth { get; set; }
}
Contact c1 = new Contact();
c1.Name = "John";
c1.YearofBirth = 1980;Contact c1 = new Contact("John", 1980);Contact c1 = new Contact { Name = "John", YearofBirth = 1980 };Contact c1 = new Contact("Wei-Meng Lee") { YearofBirth=1980 };List Contacts = new List ();
Contacts.Add(new Contact { Name = "John", YearofBirth = 1980 });
Contacts.Add(new Contact { Name = "Mary", YearofBirth = 1986 });
Contacts.Add(new Contact { Name = "Richard",YearofBirth=1948 });List Contacts = new List() {
new Contact { Name = "John", YearofBirth = 1980 },
new Contact { Name = "Mary", YearofBirth = 1986 },
new Contact { Name = "Richard", YearofBirth = 1948 }
};
#coding=utf-8
def getGeoData(ip):
"""Получить город по ip-адресу (адрес предается как строка).
Возвращает словарь с элементами-строками city, region, district
"""
import httplib
import re
from xml.dom.minidom import parseString
conn = httplib.HTTPConnection("194.85.91.253:8090")
conn.request("POST", "/geo/geo.html", \
"<ipquery><fields><all/></fields><ip-list><ip>" + ip + \
"</ip></ip-list></ipquery>")
resp = conn.getresponse()
data = resp.read()
conn.close()
# если ничего не найдено
if re.search("<message>Not found</message>", data):
return None
dom = parseString(data)
city = dom.documentElement.getElementsByTagName('city')[0]\
.firstChild.nodeValue
region = dom.documentElement.getElementsByTagName('region')[0]\
.firstChild.nodeValue
district = dom.documentElement.getElementsByTagName('district')[0]\
.firstChild.nodeValue
return {'city' : city, 'region' : region, 'district' : district}
// создание клиента очень быстрое,
// так что не обязательно делать его синглтоном
MemcachedClient client = new MemcachedClient();
// сохранить в кэше
client.Store(StoreMode.Set, "MyIntValue", 12345,
DateTime.Now.AddMinutes(20));
// получить из кэша
int value = client.Get<int>("MyIntValue");
// удалить из кэша
client.Remove("MyIntValue");
public class IncrementingNumber : Task
{
public override bool Execute()
{
NextNumber = IncrementNumber();
LastNumber = NextNumber - 1;
return true;
}
public int IncrementNumber()
{
using (FileStream fs = new FileStream(NumberFile,
FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
StreamReader reader = new StreamReader(fs);
long pos = 0;
String line = reader.ReadLine();
while (line != null && line.StartsWith("#"))
{
pos = pos +
line.Length +
System.Environment.NewLine.Length;
line = reader.ReadLine();
}
int number = -1;
if (line != null)
number = Int32.Parse(line);
NextNumber = number + 1;
fs.Position = pos;
StreamWriter writer = new StreamWriter(fs);
writer.WriteLine(NextNumber.ToString());
writer.Flush();
writer.Close();
}
return NextNumber;
}
[Required]
public string NumberFile { get; set; }
[Output]
public int NextNumber { get; set; }
[Output]
public int LastNumber { get; set; }
}
<usingtask taskname="" assemblyfile=""></usingtask>

schtasks с необходимыми параметрами. Для программистов существует хорошо документированный Com-интерфейс, но в .Net нет обертки для него. Далее будет описано, как на C# организовать работу с планировщиком заданий.
ScheduledTasks является отображением системной папки того компьютера (локального или в сети), где хранятся все файлы с заданиями.// создаем объект ScheduledTasks для машины с именем
//"DALLAS"
ScheduledTasks st = new ScheduledTasks(@"\\DALLAS");// получение списка имен задач
string[] taskNames = st.GetTaskNames();
Dispose() для освобождения этого интерфейса.TriggerList, о котором будет рассказано ниже.Save(). Функция Save(string name) работает как и Windows-функция "Сохранить как". Данный класс не имеет public конструктора. Все процедуры по созданию, открытию выполняются с помощью класса ScheduledTasks посредсвтом вызова его методов Open() или Create().// открываем задание с именем "foo" локальной машины
ScheduledTasks st = new ScheduledTasks();
Task t = st.OpenTask("foo");Для освобождения СОМ-ресурсов используем функцию Close().// закрываем задание для освобождения COM ресурса.
t.Close();Task.// получение триггеров локального задания "foo".
ScheduledTasks st = new ScheduledTasks();
Task t = st.OpenTask("foo");
TriggerList tl = t.Triggers;После закрытия задания данный список становится неактуальным.// добавление триггера для задания "foo", чтобы оно
//выполнялось в 16:30 каждый день
Trigger tg = new DailyTrigger(16, 30); // часы и минуты
ScheduledTasks st = new ScheduledTasks();
Task t = st.OpenTask("foo");
t.Triggers.Add(tg);
t.Save();Trigger :TriggerList нужного задания. Освобождать его ресурсы нет необходимости, т.к. они автоматически освобождаюся при закрытии задания. Следующия правила позволят вам избежать некоторых ошибок при программировании планировщика заданий:Clone() для создания непривязанного триггера и только потом добавить его в новый список.// получение ScheduledTasks для компьютера "DALLAS"
ScheduledTasks st = new ScheduledTasks(@"\\DALLAS");
// полученеи списка имен заданий
string[] taskNames = st.GetTaskNames();
// получение каждого задания и вывод его описания
foreach (string name in taskNames) {
Task t = st.OpenTask(name);
Console.WriteLine(" " + t.ToString());
t.Close();
}
// освобождаем COM - ресурсы.
st.Dispose();
//получение ScheduledTasks локального компьютера.
ScheduledTasks st = new ScheduledTasks();
// Создание задания с именем "D checker"
Task t;
try
{
t = st.CreateTask("D checker");
}
catch (ArgumentException)
{
Console.WriteLine("Задание с таким именем уже
существует");
return;
}
// Заполнение информации о программе для запуска
t.ApplicationName = "chkdsk.exe";
t.Parameters = "d: /f";
t.Comment = "Проверка диска D:";
// установка аккаунта, под которым будет
//происходить выполнение.
t.SetAccountInformation(@"THEDOMAIN\TheUser",
"HisPasswd");
// Говорим системе ожидать 10 мин перед запуском
//программы
t.IdleWaitMinutes = 10;
// позволяем заданию выполняться не более 2 часов,
//30 минут.
t.MaxRunTime = new TimeSpan(2, 30, 0);
// говорим системе запускать задание только при
//простое.
t.Priority = System.Diagnostics.ProcessPriorityClass.Idle;
// создаем триггер для запуска каждое воскресенье
//в 6:30.
t.Triggers.Add(new WeeklyTrigger(6, 30,
DaysOfTheWeek.Sunday));
// Сохраняемся
t.Save();
// освобождаем все ресурсы.
t.Close();
// освобождаем ресурсы.
st.Dispose();//получение ScheduledTasks локального компьютера.
ScheduledTasks st = new ScheduledTasks();
// открываем задание, которое было добавлено
Task task = st.OpenTask("D checker");
// удостоверяемся, что оно есть
if (task != null) {
// пробегаем по всем триггерам
foreach (Trigger tr in task.Triggers)
{
// если триггер имеет время начала выполнения задания,
// меняем на 4:15.
if (tr is StartableTrigger)
{
(tr as StartableTrigger).StartHour = 4;
(tr as StartableTrigger).StartMinute = 15;
}
}
task.Save();
task.Close();
}
st.Dispose();
В качестве типа проекта выбираем, что проект будет просто (не использовать никаких архетипов).
Конфигурируем проект
После того, как проект создан, нобходимо настроить зависимости gwt. Для этого можно воспользоваться инструкцией, которую написали разработчики gwt. Полученный проект выглядит так:
Так как gwt это веб-приложение, то необходимо создать в проекте папку war, в ней WEB_INF и добавить файл настройки веб-приложения web.xml. Так же добавить в WEB_INF папку lib для хранения библиотек необходимых для работы gwt.
Для того чтобы скомпилировать gwt проект можно воспользоваться build.xml, который генерируется при создании проекта для eclipse. Его необходимо отредактировать, чтобы он понимал структуру проекта maven<project name="org.test.gwtMaven"Необходимо добавить plugin к Ant для того чтобы он смог интегрироваться с maven. Подключаем plugin для данной сборки xmlns:artifact="antlib:org.apache.maven.artifact.ant">.
....default="build"
....basedir="."
....xmlns:artifact="antlib:org.apache.maven.artifact.ant">
....
</project>
<property name="gwt.version" value="1.7.0" />Создаем список файлов, который будет получен из pom для использования при сборки.
<property name="gwt.sdk" location="war/WEB-INF/gwt-sdk" />
<property name="platform" value="windows" />
<artifact:dependencies filesetId="dependency.fileset">Настройка classpath:
....<pom file="pom.xml" />
</artifact:dependencies>
<path id="project.class.path">Загруза библиотек необходимых для компиляции и работы GWT.
....<pathelement location="war/WEB-INF/classes" />
....<pathelement location="${gwt.sdk}/gwt-user-${gwt.version}.jar" />
....<fileset dir="${gwt.sdk}" includes="gwt-dev*.jar" />
....<fileset dir="${gwt.sdk}" includes="*.jar" />
....<fileset dir="war/WEB-INF/lib" includes="**/*.jar" />
</path>
<target name="libs" description="">Компиляция исходных кодов.
....<mkdir dir="war/WEB-INF/gwt-sdk" />
....<copy todir="war/WEB-INF/gwt-sdk">
........<fileset refid="dependency.fileset" />
........<mapper type="flatten" />
....</copy>
....<unzip src="${gwt.sdk}/gwt-dev-${gwt.version}-${platform}-libs.zip"
............dest="${gwt.sdk}/" />
....<copy todir="war/WEB-INF/lib"
............file="${gwt.sdk}/gwt-servlet-${gwt.version}.jar" />
</target>
<target name="javac" depends="libs" description="">Компиляция Java в JavaScript.
....<mkdir dir="war/WEB-INF/classes" />
....<javac srcdir="src/main/java"
.... ....includes="**"
.... ....encoding="utf-8"
........destdir="war/WEB-INF/classes"
........source="1.5" target="1.5"
........nowarn="true"
........debug="true"
........debuglevel="lines,vars,source">
<classpath refid="project.class.path" />
....</javac>
....<copy todir="war/WEB-INF/classes">
........<fileset dir="src/main/java" excludes="**/*.java" />
....</copy>
</target>
<target name="gwtc" depends="javac" description="">Сборка всего проекта GWT.
....<java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
........<classpath>
................<pathelement location="src/main/java" />
................<path refid="project.class.path" />
........</classpath>
........<jvmarg value="-Xmx256M" />
........<arg value="org.test.MainEntryPoint" />
....</java>
</target>
<target name="build" depends="gwtc" description="" />Упаковка проект в war файл для размещения на веб-сервере.
<target name="war" depends="build" description="">
....<zip destfile="org.test.gwtMaven.war" basedir="war" />
</target>
<target name="clean" description="">На этом редактирование build.xml пока закончим. Теперь необходимо создать класс-точку входа в gwt приложения. Для этого создадим два namespace'a. org.test и org.test.gwtMavenClient в папке исходников src/main/java. В org.test.gwtMavenClient создадим класс MainEntryPoint, который реализует интерфейс com.google.gwt.core.client.EntryPoint.
....<delete dir="war/WEB-INF/classes" failonerror="false" />
....<delete dir="war/gwt" failonerror="false" />
....<delete dir="war/WEB-INF/gwt-sdk" failonerror="false" />
....<delete dir="war/gwtMain" />
....<delete file="war/WEB-INF/lib/gwt-servlet-${gwt.version}.jar" />
</target>
В org.test создим MainEntryPoint.gwt.xml, который будет содержать настройки gwt-приложения.
package org.test.gwtMain;
import com.google.gwt.core.client.EntryPoint;
public class MainEntryPoint implements EntryPoint{
public void onModuleLoad() {
// TODO Auto-generated method stub
}
}
Дерево проекта выглядет вот так.
<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='gwtMain'>
<inherits name='com.google.gwt.user.User' />
<inherits name='com.google.gwt.i18n.I18N' />
<extend-property name="locale" values="ru_RU" />
<inherits name='com.google.gwt.user.theme.chrome.Chrome' />
<source path="gwtMain" />
<entry-point class='org.test.gwtMain.MainEntryPoint' />
</module>
Gwt-приложению необходимо где-то хоститься. Для этого в папке war необходимо создать index.html.<html>А в build.xml добавить target, который позволит запускать приложения в специальном отладочном браузере
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-language" content="ru">
<title>Insert title here</title>
<script type="text/javascript" language="javascript"
src="gwtMain/gwtMain.nocache.js"></script>
</head>
<body>
<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1'
style="position: absolute; width: 0; height: 0; border: 0"></iframe>
<div id="mainWorkSpace"></div>
</body>
</html>
<target name="hosted"Каркас готов. Продолжение следует...
....depends="javac" description="">
........<java
...............failonerror="true"
...............fork="true"
...............classname="com.google.gwt.dev.HostedMode">
............<classpath>
................<pathelement location="src/main/java" />
................<path refid="project.class.path" />
............</classpath>
............<jvmarg value="-Xmx256M" />
............<arg value="-startupUrl" />
............<arg value="index.html" />
............<arg value="org.test.MainEntryPoint" />
........</java>
</target>
static {
....try {
........DriverManager.registerDriver(new ParadoxDriver());
} catch (SQLException e) {
...
....}
}
...в папке conf/extra/ создаем файл httpd-maven2repo.conf и заносим следующую информацию:
Include conf/extra/httpd-maven2repo.conf
...
<путь_к_репо> - адрес папки в файловой системе, где будет репозиторий.
Alias /maven2repo/ "<путь_к_репо>"
Options Indexes FollowSymLinks MultiViews
Order allow,deny
Allow from all
<localrepository><путь_к_репо></localrepository>Теперь при запуске на сервере mvn install пакеты будут помещаться в наш репозиторий. А клиенты смогут получать эти пакеты через maven, указывая в качестве репозитория наш сервер.
error LGHT0204: ICE43: Component- в случае, если мы для размещения ярлыка используем атрибут Directory.has non-advertised shortcuts. It should use a registry key under HKCU as its KeyPath, not a file.
error LGHT0204: ICE57: Componenthas both per-user and per-machine data with a per-machine KeyPath.
error LGHT0204: ICE18: KeyPath for Component:is Directory: 'DesktopFolder'. The Directory/Component pair must be listed in the CreateFolders table.
error LGHT0204: ICE38: Componentinstalls to user profile. It must use a registry key under HKCU as its KeyPath, not a file.
error LGHT0204: ICE43: Componenthas non-advertised shortcuts. It should use a registry key under HKCU as its KeyPath, not a file.
// Атрибут для класса. Используется в BinarySerializer
[AttributeUsage(
AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public sealed class ClassToBinaryAttribute : Attribute
{
}
/// Атрибут для поля класса. Используется в BinarySerializer
[AttributeUsage(
AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
public sealed class FieldToBinaryAttribute : Attribute
{
}
/// <summary>
/// Контейнер для хранение сериализованных бинарных данных
/// </summary>
public abstract class BinaryContainer
{
protected List<BinaryContainer> _childs =
new List<BinaryContainer>();
/// <summary>
/// Дочерние элементы контейнера
/// </summary>
public List<BinaryContainer> Childs
{
get { return this._childs; }
}
protected byte[] _body;
/// <summary>
/// Сериализованные данные
/// </summary>
public byte[] Body
{
//get { return _body; }
set { _body = value; }
}
/// <summary>
/// Получить размер бинарной информации
/// </summary>
/// <returns></returns>
public abstract int GetBodySize();
/// <summary>
/// Получить бинарные данные
/// </summary>
/// <returns></returns>
public abstract byte[] GetBody();
}
/// <summary>
/// Контейнер для поля
/// </summary>
class BinaryField : BinaryContainer
{
public override int GetBodySize()
{
if (this._body != null)
return this._body.Length + 4;
else
return 0;
}
public override byte[] GetBody()
{
if (this._body != null)
{
// весь размер буфера: размер + данные
int fullSize = this._body.Length + 4;
byte[] newBody = new byte[fullSize];
Buffer.BlockCopy(
BitConverter.GetBytes(this._body.Length), 0, newBody, 0, 4);
Buffer.BlockCopy(
this._body, 0, newBody, 4, this._body.Length);
return newBody;
}
else
return null;
}
}
/// <summary>
/// Контейнер для класса или массива
/// </summary>
class BinaryArray : BinaryContainer
{
public int ArrayElementCount
{
get { return this._childs.Count; }
}
public override int GetBodySize()
{
int size = 4;
if (this._childs.Count > 0)
{
foreach (BinaryContainer child in this._childs)
size += child.GetBodySize();
return size;
}
else
return size;
}
public override byte[] GetBody()
{
if (this._childs.Count > 0)
{
int bodySize = this.GetBodySize();
this._body = new byte[bodySize];
Buffer.BlockCopy(
BitConverter.GetBytes(
this.ArrayElementCount), 0, this._body, 0, 4);
int offset = 4;
foreach (BinaryContainer child in this._childs)
{
int childSize = child.GetBodySize();
byte[] childBody = child.GetBody();
Buffer.BlockCopy(
childBody, 0, this._body, offset, childSize);
offset += childSize;
}
return this._body;
}
else
return new byte[4];
}
}
/// <summary>
/// Бинарный сериализатор
/// Поддержка следующих типов данных:
/// классы, массивы,
/// bool, short, int32, long(int64), float(single), double, Guid
/// Сереализация generic типов не поддерживается
/// </summary>
public class BinarySerializer
{
/// <summary>
/// Сериализация объекта
/// </summary>
/// <typeparam name="TType">Тип объекта</typeparam>
/// <param name="obj">Объект</param>
/// <returns>Массив байт</returns>
public byte[] Serialize<TType>(TType obj)
{
BinaryContainer binaryContainer = this.ClassSerializer(typeof(TType), obj);
byte[] result = binaryContainer.GetBody();
return result;
}
#region Хелперы для сериализации
/// <summary>
/// Сериализация объекта
/// </summary>
/// <param name="type">Тип объекта</param>
/// <param name="obj">Объект</param>
/// <returns>Временный контейнер</returns>
private BinaryContainer ClassSerializer(Type type, object obj)
{
// получение полей в типе
FieldInfo[] fInfos = type.GetFields(
BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public);
BinaryContainer classContainer = new BinaryArray();
foreach (FieldInfo fInfo in fInfos)
{
object[] customFieldAttributes =
fInfo.GetCustomAttributes(
ypeof(FieldToBinaryAttribute), false);
if (customFieldAttributes.Length == 1)
{
// получение аттрибута у типа поля
object[] customTypeAttributes =
fInfo.FieldType.GetCustomAttributes(
typeof(ClassToBinaryAttribute), false);
if (customTypeAttributes.Length == 1) // поле сложного типа
{
classContainer.Childs.Add(
this.ClassSerializer(fInfo.FieldType, fInfo.GetValue(obj)));
}
else // поле простого типа
{
if (fInfo.FieldType.IsArray) // поле массив
{
//сериализация массива
classContainer.Childs.Add(
this.ArraySerializer(fInfo, obj));
}
else // поле простого типа
classContainer.Childs.Add(
this.SimpleTypeSerializer(
fInfo.FieldType, fInfo.GetValue(obj)));
}
}
}
return classContainer;
}
/// <summary>
/// Сериализация массива
/// </summary>
/// <param name="fInfo">Дескриптор поля</param>
/// <param name="obj">Объект</param>
/// <returns>Бинарный контейнер с сереализованным массивом</returns>
private BinaryContainer ArraySerializer(FieldInfo fInfo, object obj)
{
// тип элемента массива
Type elementType = fInfo.FieldType.GetElementType();
Array array = (Array)fInfo.GetValue(obj);
bool isClass = false;
// получение аттрибута у типа поля
object[] customTypeAttributes =
elementType.GetCustomAttributes(
typeof(ClassToBinaryAttribute), false);
if (customTypeAttributes.Length == 1)
isClass = true;
// контейнер под хранения массива в бинарном виде
BinaryContainer binaryArray = new BinaryArray();
// испульзуем энумератор для передвижения по массиву
IEnumerator arrayEnumerator = array.GetEnumerator();
while (arrayEnumerator.MoveNext() &&
arrayEnumerator.Current != null)
{
BinaryContainer arrayElement = null;
if (isClass)
{
arrayElement =
this.ClassSerializer(
elementType, arrayEnumerator.Current);
}
else
{
// получение бинарного представления для элемента массива
arrayElement =
this.SimpleTypeSerializer(
elementType, arrayEnumerator.Current);
}
// добавление простого типа к бинарному контейнеру
binaryArray.Childs.Add(arrayElement);
}
return binaryArray;
}
/// <summary>
/// Сериализация простых типов
/// bool, short, int32, long(int64), float(single), double, Guid
/// </summary>
/// <param name="fieldType">Тип поля</param>
/// <param name="value">Значение поля</param>
/// <returns>Временный контейнер</returns>
private BinaryContainer SimpleTypeSerializer(Type fieldType, object value)
{
// буфер для хранения сериализовнных данных
byte[] buffer = null;
if (fieldType == typeof(Boolean))
{
buffer = BitConverter.GetBytes((Boolean)value);
}
else if (fieldType == typeof(Int16))
{
buffer = BitConverter.GetBytes((Int16)value);
}
else if (fieldType == typeof(Int32))
{
buffer = BitConverter.GetBytes((Int32)value);
}
else if (fieldType == typeof(Int64))
{
buffer = BitConverter.GetBytes((Int64)value);
}
else if (fieldType == typeof(Single))
{
buffer = BitConverter.GetBytes((Single)value);
}
else if (fieldType == typeof(Double))
{
buffer = BitConverter.GetBytes((Double)value);
}
else if (fieldType == typeof(Guid))
{
buffer = ((Guid)value).ToByteArray();
}
BinaryContainer tempC = null;
if (buffer != null && buffer.Length > 0)
{
tempC = new BinaryField();
tempC.Body = buffer;
}
else
throw new Exception("Ошибка в сериализациия поля типа " + fieldType.Name);
return tempC;
}
#endregion
/// <summary>
/// Десерилазиация
/// </summary>
/// <typeparam name="TType">Тип объекта</typeparam>
/// <param name="byteObj">Массив байт</param>
/// <returns>Объект заданного типа</returns>
public TType Deserialize<TType>(byte[] byteObj)
{
int offset = 0;
TType inst =
(TType)this.ClassDesirealize(
typeof(TType), byteObj, ref offset);
return inst;
}
#region Хелперы для десериализации
/// <summary>
/// Десериализация класса
/// </summary>
/// <param name="type">Тип класса</param>
/// <param name="data">Бинарные данные</param>
/// <returns>Экземпляр объекта</returns>
private object ClassDesirealize(
Type type, byte[] data, ref int offset)
{
// получение полей в типе
FieldInfo[] fInfos = type.GetFields(
BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public);
//создание объекта типа type
object obj = this.CreateInstance(type);
offset += 4; // первые 4 байта класса - количество полей
foreach (FieldInfo fInfo in fInfos)
{
object[] customFieldAttributes =
fInfo.GetCustomAttributes(
typeof(FieldToBinaryAttribute), false);
if (customFieldAttributes.Length == 1)
{
// получение аттрибута у типа поля
object[] customTypeAttributes =
fInfo.FieldType.GetCustomAttributes(
typeof(ClassToBinaryAttribute), false);
object fieldValue = null;
if (customTypeAttributes.Length == 1) // поле сложного типа
{
fieldValue =
this.ClassDesirealize(
fInfo.FieldType, data, ref offset);
}
else
{
if (fInfo.FieldType.IsArray) // поле массив
{
fieldValue =
this.ArrayDeserializer(fInfo, data, ref offset);
}
else // поле простого типа
{
// массив байт для хранения размера
byte[] sizeByte = new byte[4];
Buffer.BlockCopy(
data, offset, sizeByte, 0, sizeByte.Length);
// получение размера
int size = BitConverter.ToInt32(sizeByte, 0);
// получение данных
byte[] dataBuffer = new byte[size];
Buffer.BlockCopy(
data, offset + sizeByte.Length,
dataBuffer, 0, dataBuffer.Length);
// десериализация поля
fieldValue =
this.SimpleTypeDeserializer(
fInfo.FieldType, dataBuffer);
// увелечени сдвига по буферу
offset += sizeByte.Length + size;
}
}
// помещение значение в объект
fInfo.SetValue(obj, fieldValue);
}
}
return obj;
}
/// <summary>
/// Десериализация массива
/// </summary>
/// <param name="fInfo">Дескриптор поля</param>
/// <param name="data">Массив байт</param>
/// <param name="offset">Смещение в массиве байт</param>
/// <returns>Массив</returns>
private object ArrayDeserializer(
FieldInfo fInfo, byte[] data, ref int offset)
{
// получение количества элементов в массиве
byte[] elCountByte = new byte[4];
Buffer.BlockCopy(data, offset, elCountByte, 0, elCountByte.Length);
int elementsCount = BitConverter.ToInt32(elCountByte, 0);
// увелечение счетчика движения по буферу
offset += elCountByte.Length;
bool isClass = false;
// тип элемента массива
Type elementType = fInfo.FieldType.GetElementType();
// получение аттрибута у типа поля
object[] customTypeAttributes =
elementType.GetCustomAttributes(
typeof(ClassToBinaryAttribute), false);
if (customTypeAttributes.Length == 1)
isClass = true;
// создание экземпляра массива
Array array = Array.CreateInstance(elementType, elementsCount);
//получение элементов массива
for (int i = 0; i < elementsCount; i++)
{
object value = null;
if (isClass)
{
value =
this.ClassDesirealize(
elementType, data, ref offset);
}
else
{
if (elementType.IsArray)
{
throw new NotImplementedException(
"Ошибка при десериализации в массива ");
}
else
{
// получение размера элемента массива
byte[] elSizeByte = new byte[4];
Buffer.BlockCopy(
data, offset, elSizeByte, 0, elSizeByte.Length);
int elementSize = BitConverter.ToInt32(elSizeByte, 0);
offset += elSizeByte.Length;
//получение значения элемента массива
byte[] valueByte = new byte[elementSize];
Buffer.BlockCopy(
data, offset, valueByte, 0, valueByte.Length);
value = this.SimpleTypeDeserializer(elementType, valueByte);
offset += valueByte.Length;
}
}
// заполнение массива
array.SetValue(value, i);
}
return array;
}
/// <summary>
/// Создание экземпляра класса по его типу
/// </summary>
/// <param name="type">Тип</param>
/// <returns>Объект</returns>
private object CreateInstance(Type type)
{
ConstructorInfo constructor =
type.GetConstructor(new Type[] { });
object inst = null;
if (constructor != null)
{
inst = constructor.Invoke(new object[] { });
}
else
throw new Exception(
"Не возможно создать объект типа " +
type.Name +
". Объект должен иметь пустой конструктор");
return inst;
}
/// <summary>
/// Десериализация простых типов
/// bool, short, int32, long(int64), float(single), double, Guid
/// </summary>
/// <param name="fieldType"></param>
/// <param name="data"></param>
/// <returns></returns>
public object SimpleTypeDeserializer(Type fieldType, byte[] data)
{
object value = null;
if (fieldType == typeof(Boolean))
{
value = BitConverter.ToBoolean(data, 0);
}
else if (fieldType == typeof(Int16))
{
value = BitConverter.ToInt16(data, 0);
}
else if (fieldType == typeof(Int32))
{
value = BitConverter.ToInt32(data, 0);
}
else if (fieldType == typeof(Int64))
{
value = BitConverter.ToInt64(data, 0);
}
else if (fieldType == typeof(Single))
{
value = BitConverter.ToSingle(data, 0);
}
else if (fieldType == typeof(Double))
{
value = BitConverter.ToDouble(data, 0);
}
else if (fieldType == typeof(Guid))
{
value = new Guid(data);
}
if (value == null)
throw new Exception(
"Ошибка в десериализациия поля типа " +
fieldType.Name);
return value;
}
#endregion
}