اشتراک‌ها
Metadata Function ها در SQL Server

To be able to make full use of the system catalog to find out more about a database, you need to be familiar with the metadata functions. They save a great deal of time and typing when querying the metadata. Once you get the hang of these functions, the system catalog suddenly seems simple to use, as Robert Sheldon demonstrates in this article. 

Metadata Function ها در SQL Server
فایل‌های پروژه‌ها
PdfRpt-2.0.zip
- Fixed conflicts of default footer's font and default document's font.
- Added an optional parameter to DocumentPreferences.BackgroundImage method to specify the absolute position of the background's image.
- Enabled running in medium trust environment.
- Added PageTableAdded event. PageTableAdded Fires after each part of the MainTable has been added to the current page.
- Added CustomSummaryPerPagePdfReport sample to show how to use PageTableAdded event.

مطالب دوره‌ها
ایجاد کاتالوگ‌های Full text search و ایندکس‌های آن
جستجو بر روی خواص و متادیتای اسناد آفیس

همانطور که در قسمت قبل نیز عنوان شد، فیلترهای FTS آفیس، علاوه بر اینکه امکان جستجوی پیشرفته FTS را بر روی کلیه فایل‌های مجموعه آفیس میسر می‌کنند، امکان جستجوی FTS را بر روی خواص ویژه اضافی آن‌ها، مانند نام نویسنده، واژه‌های کلیدی، تاریخ ایجاد و امثال آن نیز به همراه دارند.
اینکه چه خاصیتی را بتوان جستجو کرد نیز بستگی به نوع فیلتر نصب شده دارد. برای تعریف خواص قابل جستجوی یک سند، باید یک SEARCH PROPERTY LIST را ایجاد کرد:
CREATE SEARCH PROPERTY LIST WordSearchPropertyList;
GO

ALTER SEARCH PROPERTY LIST WordSearchPropertyList
   ADD 'Authors'
   WITH (PROPERTY_SET_GUID = 'F29F85E0-4FF9-1068-AB91-08002B27B3D9',
             PROPERTY_INT_ID = 4,
             PROPERTY_DESCRIPTION = 'System.Authors - authors of a given item.');
GO
در این تعریف، PROPERTY_INT_ID و PROPERTY_SET_GUIDها استاندارد بوده و لیست آن‌ها را در آدرس ذیل می‌توانید مشاهده نمائید:


بهبود کیفیت جستجو توسط Stop lists و Stop words

به یک سری از کلمات و حروف، اصطلاحا noise words گفته می‌شود. برای مثال در زبان انگلیسی حروف و کلماتی مانند a، is، the و and به صورت خودکار از FTS حذف می‌شوند؛ چون جستجوی آن‌ها بی‌حاصل است. به این‌ها stop words نیز می‌گویند.
با استفاده از کوئری ذیل می‌توان لیست stop words تعریف شده در بانک اطلاعاتی جاری را مشاهده کرد:
 -- Check the Stopwords list
SELECT w.stoplist_id,
   l.name,
   w.stopword,
   w.language
FROM sys.fulltext_stopwords AS w
   INNER JOIN sys.fulltext_stoplists AS l
     ON w.stoplist_id = l.stoplist_id;
و برای تعریف stop words از دستورات ذیل کمک گرفته می‌شود:
 -- Stopwords list
CREATE FULLTEXT STOPLIST SQLStopList;
GO

-- Add a stopword
ALTER FULLTEXT STOPLIST SQLStopList
 ADD 'SQL' LANGUAGE 'English';
GO


کاتالوگ‌های Full Text Search

ایندکس‌های ویژه‌ی FTS، در مکان‌هایی به نام Full Text Catalogs ذخیره می‌شوند. این کاتالوگ‌ها صرفا یک شیء مجازی بوده و تنها برای تعریف ظرفی دربرگیرنده‌ی ایندکس‌های FTS تعریف می‌شوند. در نگارش‌های پیش از 2012 اس کیوال سرور، این کاتالوگ‌ها اشیایی فیزیکی بودند؛ اما اکنون تبدیل به اشیایی مجازی شده‌اند.
حالت کلی تعریف یک fulltext catalog به نحو ذیل است:
 create fulltext catalog catalog_name
on filegroup filegroup_name
in path  'rootpath'
with some_options
as default
authoriztion owner_name
accent_sensivity = {on|off}
اما اکثر گزینه‌های آن مانند on filegroup و in path صرفا برای حفظ سازگاری با نگارش‌های قبلی حضور دارند و دیگر نیازی به ذکر آن‌ها نیست؛ چون تعریف کننده‌ی ماهیت فیزیکی این کاتالوگ‌ها می‌باشند.
به صورت پیش فرض حساسیت به لهجه یا accent_sensivity خاموش است. اگر روشن شود، باید کل ایندکس مجددا بازسازی شود.


ایجاد ایندکس‌های Full Text

پس از ایجاد یک fulltext catalog، اکنون نوبت به تعریف ایندکس‌هایی فیزیکی هستند که داخل این کاتالوگ‌ها ذخیره خواهند شد:
 -- Full-text catalog
CREATE FULLTEXT CATALOG DocumentsFtCatalog;
GO

-- Full-text index
CREATE FULLTEXT INDEX ON dbo.Documents
(
  docexcerpt Language 1033,
  doccontent TYPE COLUMN doctype
  Language 1033
  STATISTICAL_SEMANTICS
)
KEY INDEX PK_Documents
ON DocumentsFtCatalog
WITH STOPLIST = SQLStopList,
  SEARCH PROPERTY LIST = WordSearchPropertyList,
  CHANGE_TRACKING AUTO;
GO
در اینجا توسط KEY INDEX نام منحصربفرد ایندکس مشخص می‌شود.
CHANGE_TRACKING AUTO به این معنا است که SQL Server به صورت خودکار کار به روز رسانی این ایندکس را با تغییرات رکوردها انجام خواهد داد.
ذکر STATISTICAL_SEMANTICS، منحصر به SQL Server 2012 بوده و کار آن تشخیص واژه‌های کلیدی و ایجاد ایندکس‌های یافتن اسناد مشابه است. برای استفاده از آن حتما نیاز است مطابق توضیحات قسمت قبل، Semantic Language Database پیشتر نصب شده باشد.
توسط STOPLIST، لیست واژه‌هایی که قرار نیست ایندکس شوند را معرفی خواهیم کرد. SQLStopList را در ابتدای بحث ایجاد کردیم.
Language 1033 به معنای استفاده از زبان US English است.
نحوه‌ی استفاده از SEARCH PROPERTY LIST ایی که پیشتر تعریف کردیم را نیز در اینجا ملاحظه می‌کنید.


مثالی برای ایجاد ایندکس‌های FTS

برای اینکه ربط منطقی نکات عنوان شده را بهتر بتوانید بررسی و آزمایش کنید، مثال ذیل را درنظر بگیرید.
ابتدا جدول Documents را برای ذخیره سازی تعدادی سند، ایجاد می‌کنیم:
 CREATE TABLE dbo.Documents
(
  id INT IDENTITY(1,1) NOT NULL,
  title NVARCHAR(100) NOT NULL,
  doctype NCHAR(4) NOT NULL,
  docexcerpt NVARCHAR(1000) NOT NULL,
  doccontent VARBINARY(MAX) NOT NULL,
  CONSTRAINT PK_Documents
PRIMARY KEY CLUSTERED(id)
);
اگر به این جدول دقت کنید، هدف از آن ذخیره‌ی اسناد آفیس است که فیلترهای FTS آن‌را در قسمت قبل نصب کردیم. ستون doctype، معرف نوع سند و doccontent ذخیره کننده‌ی محتوای کامل سند خواهند بود.

سپس اطلاعاتی را در این جدول ثبت می‌کنیم:
-- Insert data
-- First row
INSERT INTO dbo.Documents
(title, doctype, docexcerpt, doccontent)
SELECT N'Columnstore Indices and Batch Processing', 
 N'docx',
 N'You should use a columnstore index on your fact tables,
   putting all columns of a fact table in a columnstore index. 
   In addition to fact tables, very large dimensions could benefit 
   from columnstore indices as well. 
   Do not use columnstore indices for small dimensions. ',
 bulkcolumn
FROM OPENROWSET
 (BULK 'C:\Users\Vahid\Desktop\Updates\fts_docs\ColumnstoreIndicesAndBatchProcessing.docx', 
  SINGLE_BLOB) AS doc;

-- Second row
INSERT INTO dbo.Documents
(title, doctype, docexcerpt, doccontent)
SELECT N'Introduction to Data Mining', 
 N'docx',
 N'Using Data Mining is becoming more a necessity for every company 
   and not an advantage of some rare companies anymore. ',
 bulkcolumn
FROM OPENROWSET
 (BULK 'C:\Users\Vahid\Desktop\Updates\fts_docs\IntroductionToDataMining.docx', 
  SINGLE_BLOB) AS doc;

-- Third row
INSERT INTO dbo.Documents
(title, doctype, docexcerpt, doccontent)
SELECT N'Why Is Bleeding Edge a Different Conference', 
 N'docx',
 N'During high level presentations attendees encounter many questions. 
   For the third year, we are continuing with the breakfast Q&A session. 
   It is very popular, and for two years now, 
   we could not accommodate enough time for all questions and discussions! ',
 bulkcolumn
FROM OPENROWSET
 (BULK 'C:\Users\Vahid\Desktop\Updates\fts_docs\WhyIsBleedingEdgeADifferentConference.docx', 
  SINGLE_BLOB) AS doc;

-- Fourth row
INSERT INTO dbo.Documents
(title, doctype, docexcerpt, doccontent)
SELECT N'Additivity of Measures', 
 N'docx',
 N'Additivity of measures is not exactly a data warehouse design problem. 
   However, you have to realize which aggregate functions you will use 
   in reports for which measure, and which aggregate functions 
   you will use when aggregating over which dimension.',
 bulkcolumn
FROM OPENROWSET
 (BULK 'C:\Users\Vahid\Desktop\Updates\fts_docs\AdditivityOfMeasures.docx', 
  SINGLE_BLOB) AS doc;
GO
4 ردیف ثبت شده در جدول اسناد، نیاز به 4 فایل docx نیز دارند که آن‌ها را از آدرس ذیل می‌توانید برای تکمیل ساده‌تر آزمایش دریافت کنید:
fts_docs.zip

در ادامه می‌خواهیم قادر باشیم تا بر روی متادیتای نویسنده‌ی این اسناد نیز جستجوی کامل FTS را انجام دهیم. به همین جهت SEARCH PROPERTY LIST آن‌را نیز ایجاد خواهیم کرد:
 -- Search property list
CREATE SEARCH PROPERTY LIST WordSearchPropertyList;
GO
ALTER SEARCH PROPERTY LIST WordSearchPropertyList
 ADD 'Authors'
 WITH (PROPERTY_SET_GUID = 'F29F85E0-4FF9-1068-AB91-08002B27B3D9',
PROPERTY_INT_ID = 4,
PROPERTY_DESCRIPTION = 'System.Authors - authors of a given item.');
GO
همچنین می‌خواهیم از واژه‌ی SQL در این اسناد، در حین ساخت ایندکس‌های FTS صرفنظر شود. برای این منظور یک FULLTEXT STOPLIST را به نام SQLStopList ایجاد کرده و سپس واژه‌ی مدنظر را به آن اضافه می‌کنیم:
 -- Stopwords list
CREATE FULLTEXT STOPLIST SQLStopList;
GO
-- Add a stopword
ALTER FULLTEXT STOPLIST SQLStopList
 ADD 'SQL' LANGUAGE 'English';
GO
صحت عملیات آن‌را توسط کوئری «Check the Stopwords list» ذکر شده در ابتدای بحث می‌توانید بررسی کنید.

اکنون زمان ایجاد یک کاتالوگ FTS است:
 -- Full-text catalog
CREATE FULLTEXT CATALOG DocumentsFtCatalog;
GO
با توجه به اینکه در نگارش‌های جدید SQL Server این کاتالوگ صرفا ماهیتی مجازی دارد، ساده‌ترین Syntax آن برای کار ما کفایت می‌کند.
و در آخر ایندکس FTS ایی را که پیشتر در مورد آن بحث کردیم، ایجاد خواهیم کرد:
 -- Full-text index
CREATE FULLTEXT INDEX ON dbo.Documents
(
  docexcerpt Language 1033,
  doccontent TYPE COLUMN doctype
  Language 1033
  STATISTICAL_SEMANTICS
)
KEY INDEX PK_Documents
ON DocumentsFtCatalog
WITH STOPLIST = SQLStopList,
  SEARCH PROPERTY LIST = WordSearchPropertyList,
  CHANGE_TRACKING AUTO;
GO



در این تصویر محل یافتن اجزای مختلف Full text search را در management studio مشاهده می‌کنید.


یک نکته‌ی تکمیلی
برای زبان فارسی نیز یک سری stop words وجود دارند. لیست آن‌ها را از اینجا می‌توانید دریافت کنید:
stopwords.sql
متاسفانه زبان فارسی جزو زبان‌های پشتیبانی شده توسط FTS در SQL Server نیست (نه به این معنا که نمی‌توان با آن کار کرد؛ به این معنا که برای مثال دستورات صرفی زبان را ندارد) و به همین جهت از زبان انگلیسی در اینجا استفاده شده‌است.
اشتراک‌ها
اکنون می توانید توسط یک افزونه هر برنامه NET. را به آخرین نسخه دات نت در داخل ویژوال استودیو ارتقا دهید

Now you can upgrade any .NET application to the latest version of .NET inside of Visual Studio! We are happy to introduce it as a Visual Studio extension and will upgrade your .NET Framework or .NET Core web- and desktop apps. In this video, Olia shows you how to get the extension and start to update your projects to the latest version of NET in minutes. 


اکنون می توانید توسط یک افزونه هر برنامه NET. را به آخرین نسخه دات نت در داخل ویژوال استودیو ارتقا دهید
مطالب
خلاصه‌ای کاربردی در مورد Observable collection

Observable collection در WPF را می‌توان نوعی لیست جنریک ویژه تعریف کرد که زمانیکه به کنترلی بایند شد، کنترل را از تغییرات خودش آگاه می‌کند. برای مثال اگر آیتمی به این لیست اضافه شد بلافاصله آن آیتم را در کنترل مقید به آن نیز خواهید دید، به همین ترتیب در مورد ویرایش و یا حذف یک آیتم، بدون نیاز به کوچکترین تماسی با کنترل مورد نظر. برای مثال اگر مقدار یک خاصیت را تغییر دادید، بلافاصله بدون اینکه به کنترل مقید به آن اعلام کنیم که لطفا این مورد ویژه را برای من تغییر بده، شاهد نتیجه‌ی نهایی خواهیم بود.



اما استفاده‌ی پیشرفته از این لیست جنریک ویژه به همینجا ختم نشده و حین اضافه کردن کمی پیچیدگی به برنامه مشکلات عدیده‌ای بروز می‌کنند که آن‌ها را جهت دسترسی ساده‌ی بعدی در زیر لیست می‌کنم:

الف) اصلا Observable collection چیست؟ چکار می‌کند؟
List vs ObservableCollection vs INotifyPropertyChanged in Silverlight

ب) نمی‌توانم از این مجموعه‌ی اشیای خودآگاه سازنده در یک ترد استفاده کنم. مشکل کجاست؟
این روزها نمی‌توان یک برنامه‌ی دسکتاپ خوب را بدون استفاده از تردها متصور شد. اما به محض سعی در به روز رسانی این لیست جنریک در یک ترد دیگر (ترد دیگر منظور هر تردی بجز ترد اصلی برنامه است که کار مدیریت رابط کاربر را به عهده دارد) خطای زیر ظاهر می‌شود:
This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread

راه حل:
Adding to an ObservableCollection from a background thread

ج) یکی از خاصیت‌های یک شیء این لیست جنریک ویژه را تغییر داده‌ام. اما هیچ تغییری در کنترل بایند شده به آن مشاهده نمی‌کنم. مشکل در کجاست؟
راه حل: پیاده سازی اینترفیس INotifyPropertyChanged را فراموش کرده‌اید:
Data Binding in WPF with the Monostate Pattern

د) خوب، این که خیلی دردسر دارد! راه ساده‌تری برای تعریف این موارد نیست؟!
هوشمندانه‌ترین روشی که برای حل این مساله تابحال دیده‌ام:
An easier way to manage INotifyPropertyChanged

ه) زمانیکه این یک لیست جنریک خودآگاه سازنده را به یک مثلا listview بایند می‌کنم، دیگر نمی‌توانم با استفاده از متد clear items آن کنترل، نسبت به خالی کردن نمای ظاهری آن اقدام کنم. چکار باید کرد؟
خطای مشاهده شده:
Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead

راه حل:
همان Observable collection اصلی را تخلیه کنید، UI به صورت خودکار به روز خواهد شد.

و) اضافه کردن رنجی از اطلاعات به آن به صورتی یکباره ممکن است کند باشد. چه باید کرد؟
راه حل:
AddRange for ObservableCollection in Silverlight 3


مطالب
مقایسه value type و reference type
در سی شارپ دو نوع class و struct وجود دارد که تقریباً مشابه یکدیگرند در حالیکه یکی از آنها-value type و دیگری reference-type است.

struct چیست؟
structها مشابه classها هستند با این تفاوت که structها finalizer ندارند و از ارث بری پشتیبانی نمی‌کنند. structها کاملا مشابه classها تعریف می‌شوند و در تعریف آنها از کلمه کلیدی struct استفاده می‌شود. آنها شامل فیلدها، متدها، خصوصیت‌ها نیز می‌شوند. در زیر نحوه تعریف آن را مشاهده می‌کنید: 

struct Point
{
   private int x, y;             // private fields
 
   public Point (int x, int y)   // constructor
   {
         this.x = x;
         this.y = y;
   }

   public int X                  // property
   {
         get {return x;}
         set {x = value;}
   }

   public int Y
   {
         get {return y;}
         set {y = value;}
   }
}

value type و reference type
تفاوت دیگری که بین class و struct، از اهمیت ویژه‌ای برخوردار است  آن است که classها reference-type و structها value-type هستند و در زمان اجرا با آنها متفاوت رفتار می‌شود و در ادامه به تشریح آن می‌پردازیم.
وقتی یک وهله از value-type ایجاد شود، یک فضای خالی از حافظه‌ی اصلی (RAM) برای ذخیره سازی مقدار آن تخصیص داده می‌شود. نوع‌های اصلی مانند int, float, bool و char از نوع value type هستند. در ضمن سرعت دسترسی به آنها بسیار بالاست.
ولی وقتی یک وهله از reference-type ایجاد شود، یک فضا برای object و فضایی دیگر برای اشاره‌گر به آن شیء در حافظه اصلی ذخیره می‌شود. در واقع دو فضا از حافظه برای ذخیره سازی آنها اشغال می‌شود. برای درک بهتر به مثال زیر توجه کنید:
Point p1 = new Point();         // Point is a *struct*
Form f1 = new Form();           // Form is a *class*
نکته: Point از نوع struct و Form از نوع reference است. در مورد اول، یک فضا از حافظه برای p1 تخصیص داده می‌شود و در مورد دوم، دو فضا از حافظه اصلی یکی برای ذخیره کردن اشاره‌گر f1 برای اشاره به Form object و دیگری برای ذخیره کردن Form object تخصیص داده می‌شود.
Form f1;                        // Allocate the reference
f1 = new Form();                // Allocate the object
به قطعه کد زیر دقت کنید:
Point p2 = p1;
Form f2 = f1;
همانطور که قبلاً گفته شد p2، یک نوع struct است بنابراین در مورد اول مقدار p2 یک کپی از مقدار p1 خواهد بود ولی در مورد دوم، آدرس f1 را درون f2 کپی می‌کنیم در واقع f1 و f2 به یک شیء اشاره خواهند کرد. (یک شیء با 2 اشاره گر)
در سی شارپ، پارامترها (بصورت پیش فرض) بصورت یک کپی از آنها به متدها ارسال می‌شوند، یعنی اگر پارامتر از نوع value-type باشد یک کپی از آن وهله و اگر پارامتر reference-type یک کپی از آدرس ارسال خواهد شد. برای توضیح بهتر به مثال زیر توجه کنید:
Point myPoint = new Point (0, 0);      // a new value-type variable
Form myForm = new Form();              // a new reference-type variable
Test (myPoint, myForm);                // Test is a method defined below
 
void Test (Point p, Form f)
{
      p.X = 100;                       // No effect on MyPoint since p is a copy
      f.Text = "Hello, World!";        // This will change myForm’s caption since
                                       // myForm and f point to the same object
      f = null;                        // No effect on myForm
}
انتساب null به f درون متد Test هیچی اثری بر روی آدرس myForm ندارد چون f، یک کپی از آدرس myForm است.
حال می‌توانیم روش پیش فرض را با افزودن کلمه کلید ref تغییر دهیم.  وقتی از ref استفاده کنیم متد با پارامترهای فراخوانی کننده (caller's arguments) بصورت مستقیم در تعامل است در کد زیر می‌توانیم تصور کنیم که پارامترهای p و f متد Test همان متغیرهای myPoint و myForm است.
Point myPoint = new Point (0, 0);      // a new value-type variable
Form myForm = new Form();              // a new reference-type variable
Test (ref myPoint, ref myForm);        // pass myPoint and myForm by reference
 
void Test (ref Point p, ref Form f)
{
      p.X = 100;                       // This will change myPoint’s position
      f.Text = “Hello, World!”;        // This will change MyForm’s caption
      f = null;                        // This will nuke the myForm variable!
}
در کد بالا انتساب null به f باعث تهی شدن myForm می‌شود بدلیل اینکه متد مستقیماً به آن دسترسی داشته است.

تخصیص حافظه
CLR اشیاء را در دو قسمت ذخیره می‌کند:
  1. stack یا پشته
  2. heap
ساختار stack یا پشته first-in last-out است که دسترسی به آن سریع است. زمانی که متدی فراخوانی می‌شود، CLR پشته را نشانه گذاری می‌کند. سپس متد data را به پشته جهت اجرا push می‌کند و زمانی که اجرایش به اتمام رسید، CLR پشته را تا محل نشانه گذاری شده مرحله قبل، پاک می‌کند (pop).
ولی ساختار heap بصورت تصادفی است. یعنی اشیاء در محل‌های تصادفی قرار داده می‌شوند بهمین دلیل آنها دارای 2 سربار memory manager و garbage-collector هستند.
برای آشنایی با نحوه استفاده پشته و heap به کد زیر توجه کنید:
void CreateNewTextBox()
{
      TextBox myTextBox = new TextBox();             // TextBox is a class
}
در این متد، ما یک متغیر محلی ایجاد کرده ایم که به یک شیء اشاره می‌کند.

پشته همیشه برای ذخیره سازی موارد زیر استفاده می‌شود:
  • قسمت reference متغیرهای محلی و پارامترهای از نوع reference-typed (مانند myTextBox)
  • متغیرهای محلی و پارامترهای متد از نوع value-typed (مانند integer, bool, char, DateTime و ...)
همچنین از heap برای ذخیره سازی موارد زیر استفاده می‌شود:
  • محتویات شیء از نوع reference-typed
  • هر چیزی که قرار است در شیء از نوع reference-typed ذخیره شود.

آزادسازی حافظه در heap

در کد بالا وقتی اجرای متد CreateNewTextBox به اتمام برسد متغیر myTextBox از دید (Scope) خارج می‌شود. بنابراین از پشته نیز خارج می‌شود ولی با خارج شدن myTextBox از پشته چه اتفاقی برای TextBox object رخ خواهد داد؟! پاسخ در garbage-collector نهفته است. garbage-collector بصورت خودکار عملیات پاکسازی heap را انجام می‌دهد و اشیائی که اشاره گر معتبر ندارند را حذف می‌نماید. در حالت کلی اگر شیء از حافظه خارج شد باید منابع سایر قسمت‌های اشغال شده توسط آن هم آزاد شود، که این آزاد سازی بعهده garbage-collector است.

حال آزاد سازی برای کلاسهایی که اینترفیس IDisposable را پیاده سازی می‌کنند به دو صورت انجام می‌شود:

  1. دستی: با فراخوانی متد Dispose میسر است.
  2. خودکار: افزودن شیء به Net Container. مانند Form, Panel, TabPage یا UserControl. این نگهدارندها این اطمینان را به ما می‌دهند در صورتیکه آنها از حافظه خارج شدند کلیه عضوهای آن هم از حافظه خارج شوند.

برای آزادسازی دستی می‌توانیم مانند کدهای زیر عمل کنیم:

using (Stream s = File.Create ("myfile.txt"))

{
   ...
}
یا
Stream s = File.Create ("myfile.txt");

try
{
   ...
}

finally
{
   if (s != null) s.Dispose();
}


مثالی از Windows Forms
فرض کنید قصد داریم فونت و اندازه یک ویندوز فرم را تغییر دهیم.

Size s = new Size (100, 100);          // struct = value type
Font f = new Font (“Arial”,10);        // class = reference type

Form myForm = new Form();

myForm.Size = s;
myForm.Font = f;
توجه کنید که ما در کد بالا از اعضای myForm استفاده کردیم نه از کلاسهای Font و Size که این دو گانگی قابل قبول است. حال به تصویر زیر که به پیاده سازی کد بالا اشاره دارد توجه کنید.

همانطور که مشاهد می‌کنید محتویات s و آدرس f را در Form object ذخیره کرده ایم که نشان می‌دهد تغییر در s برروی فرم تغییر ایجاد نمی‌کند ولی تغییر در f باعث ایجاد تغییر فرم می‌شود. Form object دو اشاره گر به Font object دارد.

In-Line Allocation (تخصیص درجا)
در قبل گفته شد برای ذخیره متغیرهای محلی از نوع value-typed از پشته استفاده می‌شود آیا شیء Size جدید هم در پشته ذخیره می‌شود؟ خیر، بدلیل اینکه آن متغیر محلی نیست و در شیء دیگر ذخیره می‌شود (در مثال بالا در یک فرم ذخیره شده است) که آن شیء هم در heap ذخیره شده است پس شیء جدید Size هم در heap ذخیر می‌شود که به این نوع ذخیره سازی In-Line گفته می‌شود.

تله (Trap)
فرض کنید کلاس Form بشکل زیر تعریف شده است:
class Form
{
      // Private field members
      Size size;
      Font font;

      // Public property definitions
      public Size Size
      {
            get    { return size; }
            set    { size = value; fire resizing events }
      }

      public Font Font
      {
            get    { return font;  }
            set    { font = value; }
      }
}
حال ما قصد داریم ارتفاع آن را دو برابر کنیم، بنابراین از کد زیر استفاده می‌کنیم:
myForm.ClientSize.Height = myForm.ClientSize.Height * 2;
ولی با خطای کامپایلر زیر روبرو می‌شویم:
Cannot modify the return value of 'System.Windows.Forms.Form.ClientSize' because it is not a variable
علت چیست؟ بدلیل اینکه myForm.ClientSize شیء Size که از نوع Struct است را بر می‌گرداند و این Struct از نوع value-typed است و این شیء یک کپی از اندازه فرم است و ما همزمان قصد دو برابر نمودن آن کپی را داریم که کامپایلر خطای بالا را نمایش می‌دهد.

برای توضیح بیشتر می‌توانید به این سوال مراجعه کنید و در تکمیل آن این لینک را هم بررسی کنید.

پس بنابراین کد بالا را به کد زیر اصلاح می‌کنیم:
myForm.ClientSize = new Size (myForm.ClientSize.Width, myForm.ClientSize.Height * 2);
برای اصلاح خطای کامپایلر، ما باید یک شیء جدیدی را برای اندازه فرم تخصیص بدهیم.
بازخوردهای دوره
نگاهی به SignalR Hubs
با سلام

من یک برنامه وب فرم دارم که کلاینت signalr من می‌باشد. این برنامه در شرایط معمولی به درستی کار می‌کند و ارتباط برقرار می‌شود.
ولی زمانی که در کامپیوتر از kerio control vpn client  استفاده می‌کنم، و برنامه وب فرم را باز می‌کنم، برنامه در کنسول خطای زیر را نمایش می‌دهد:
Uncaught Error: SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. <script src='/signalr/js'></script>.
    at Object.start (jquery.signalR-2.4.0.min.js:9)
    at HTMLDocument.<anonymous> (Default.aspx:716)
.......


hubs:1 Failed to load resource: net::ERR_CONNECTION_TIMED_OUT
متوجه شدم که خطا در این خط ایجاد می‌شود:
 $.connection.hub.start().done(function ()
آیا می‌توانید در این مورد من رو راهنمایی کنید؟
اشتراک‌ها
ارتقاء در WPF و Sql Connectivity در نسخه 4.6.1 .net Framework

Microsoft's .NET Fundamentals Team a few weeks ago announced a new version of .NET Framework 4.6.1. It includes a number of streamline improvements to Windows Presentation Foundation and SQL Connectivity, to name a few. And just recently, the team also re-emphasized end of support for versions of .NET Framework versions older than 4.5.1.  

ارتقاء در WPF و Sql Connectivity  در نسخه 4.6.1 .net Framework