Tuesday, March 22, 2016

Manifest, GAC i Refleksija


Pre nego što pređemo na Manifest, podsetio bi vas da dobro prostudirate dva prethodna posta Arhitektura Microsoft .NET Framework-a i Šta su sklopovi? Koje sve komponente sadrži .Net Framework i koji je proces kompajliranja i izvršavanja aplikacija programiranih u .Net programskim jezicima je toliko bitno znati, da ćemo prvo u najkraćim crtama ponoviti materiju koja se mora znati. Znači, Microsoft .Net Framework je platforma koja omogućava razvoj i izvršavanje .Net aplikacija. To je platforma koje obezbeđuje komponentnu infrastrukturu, integraciju programskih jezika, internet interoperabilnost, jednostavan razvoj, jednostavnu instalaciju, pouzdanost i bezbednost. CLR – Common Language Runtime je najvažniji deo Microsoft .Net Framework-a nadležan za aktiviranje objekata, izvršavanje bezbednosnih provera nad njima, njihovo smeštanje u memoriju, izvršavanje i uklanjanje iz memorije. CLR podržava sve programske jezike koje se mogu prevesti u MSIL – Microsoft Intermediate Language. 
 

( Sklop u jednom i sklop u više fajlova )

Sledeće komponente Microsoft .Net Framework-a su BCL – Base Class Library, biblioteka baznih klasa koja se sastoji se od klasa, interfejsa i tipova podataka koje omogućavaju korišćenje funkcija sistema i FCL – Framework Class Library koja sadrži specijalizovane biblioteke tipova podataka koje sadrže Data i XML klase. Microsoft .Net Framework sadrži i klase koje omogućavaju tehnologije za razvoj aplikacija poput konzolni aplikacija, formi, WPF aplikacija, univerzalni aplikacija, mobilni aplikacija, web servisa, web aplikacija itd. Proces prevođenja izvornog koda u izvršni u najkraćim crtama se može podeliti u dva koraka. Prvo se izvorni kod prevodi u MSIL – Microsoft Intermediate Language, zatim u mašinski kod. MSIL je jezik nižeg nivoa koji se lako pretvara u mašinski kod. On omogućuje platformsku nezavisnost, poboljšanje performansi i jezičku interoperabilnost. Jednostavno klasa koja je napisana u jednom programskom jeziku može da komunicira sa klasom pisanom u drugom programskom jeziku. CTS – Common Type System – zajednički sistem tipova definiše skup pravila koje .Net kompajleri moraju da poštuju. CTS tipovi imaju istu semantiku bez obzira u kom su programskom jeziku definisani. I naravno ne treba izostaviti ni GC – Garbidge Collection – skupljač smeća, komponentu za upravljanje memorijom. GC jedino radi sa referentnim tipovima podataka, što znači da objekte na hipu do kojih ne vodi ni jedna referenca se automatski oslobađa. GC sprečava curenje memorije, tačno vreme oslobađanja memorije nije određeno i oslobađanje resursa ne treba da se radi u destruktoru klase.

Gde se sad u sve navedeno uklapa sklop? 
 
Sklop je osnovna jedinica aplikacije .Net-a. Sklop je samoopisujuća kolekcija koda, resursa i meta podataka. Jednostavno govoreći, sklop je projekat koji se kompajlira u izvršnu datoteku *.exe ili u *.dll datoteku biblioteke. Sklop je deo vaše aplikacije, projekta ili rešenja, ne deo Microsoft .Net Framework-a. Vaša izvršna datoteka i klase koje pravite sadrže sklop. Sklop može biti javni tj. deljeni ili privatni. Deljeni sklopovi se instaliraju u poseban folder GAC - Global Assembly Cache folder; C:\Windows\Microsoft.NET\assembly\GAC_MSIL i mogu ih koristiti i druge aplikacije dok privatni sklop se nalazi u direktorijumu aplikacije. Samo da napomenem da su se pre verzije Microsoft .Net Framework-a 4.0, GAC folder nalazio u C:\Windows\assembly i da ga još uvek koriste starije aplikacije. Tek kad pogledate strukturu sklopa dolazimo do Manifest sklopa ili skraćeno rečeno Manifest. Bez obzira koliko imate datoteka sklopova u jednoj datoteci se uvek moraju nalaziti Manifest sklopa. Manifest sklopa nije isto što i meta podaci iako programeri imaju takav utisak.

Šta je Manifest?

Sklop se sastoji od meta podataka sklopa koji opisuju celi sklop, meta podataka tipa koji opisuju izvezene tipove i metode, MSIL koda i resursa. Meta podaci opisuju sadržaj sklopa dok Manifest opisuje sam sklop. Znači, sklop sadrži Manifest, dok Manifest sadrži meta podatke plus dodatne tabele. Meta podaci opisuju sami sebe, dok Manifest uključuje i reference vanjskih klasa, zavisnosti od drugih sklopova i informacije (tabele) o meta podacima. Meta podaci se nalaze u sklopovima i modulima dok je Manifest uvek prikazan u sklopovima. Manifest nije ništa već ekstra tabela u selekciji meta podataka PE – Portable Executable fajla koji sadrži:

  • Assembly Name – ime sklopa, tekst tipa string koji sadrži ime sklopa
  • Version Number – verzija sklopa
  • Culture – informacije o kulturi ili jeziku koje sklop podržava. Ukoliko sklop sadrži informacije o kulturi, takav sklop se smatra satellite assembly – satelitski sklop
  • Strong Name – strogo ime, javni ključ proizvođača ukoliko je definisano strogo ime
  • Lista svih fajlova u sklopu – svi fajlovi koji čine sklop uključujući i fajl koji sadrži manifest moraju biti u istom direktorijumu
  • Type reference information – informacije o referentnim tipovima koji će se izvoziti iz sklopa
  • Lista referencirani sklopova – informacije o drugim sklopovima koji statički referenciraju sklop


( Struktura Manifest-a )

Kako možemo videti manifest u praktičnom primeru?

Napravićemo jednostavnu konzolnu aplikaciju koja nam ukazuje da se radi o privatnom sklopu. Nazvaćemo je MyManifest, unesite sledeći kod:

using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyManifest
{
    class Program
    {
        static void Main(string[] args)
        {
            WriteLine("This is a private assembly!");
            WriteLine(Environment.NewLine + "Press any key to continue...");
            ReadKey();

        }
    }
}

Pokrenite aplikaciju da se kompajlira, ali ne u Debug modu, već u Release.

This is a private assembly!

Press any key to continue...


U Solution Explorer kliknite desnim tasterom miša na projekat MyManifest i u meniju kliknite na Properties. Ukoliko vam je selektovan Application tab, kliknite na dugme Assembly information. Kad vam se otvori forma za unos informacija o sklopu, unesite ili promenite neke informacije, na primer unesite vaše ime kompanije i kopirajta.


( Assembly Information forma desno )

Potvrdite vaš unos pritiskom levog tastera miša na dugme OK i vratite se na Solution Explorer. U Solution Explorer pronađite datoteku AssemblyInfo.cs i kliknite na datoteku levim tasterom miša. Videćete da su se informacije u datoteci takođe promenile. Vi možete i direktno u navedenom fajlu da menjate informacije o vašem sklopu.

using System.Resources;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("MyManifest")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Manuel Corporation")]
[assembly: AssemblyProduct("MyManifest")]
[assembly: AssemblyCopyright("Manuel Corporation Copyright ©  2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components.  If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("3dc9d0d8-f278-4cfb-8345-300d80e42718")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: NeutralResourcesLanguage("en-US")]

Isključite tab prikaz navedene datoteke i kliknite na Windows Explorer ili File Explorer u zavisnosti koji Windows operativni sistem koristite. Pronađite direktorijum vašeg Programa MyManifest; zatim direktorijum Release. Kliknite desnim tasterom miša na MyManifest.exe fajl i na meniju kliknite levim tasterom miša na Properties. Pogledajte tab Details i videćete takođe informacije koje ste promenili.


( Properties - Details datoteke MyManifest.exe )

Zatvorite Windows Explorer ili File Explorer i otvorite Developer Command Prompt. U zavisnosti od direktorijuma gde ste usnimili vašu aplikaciju, otkucajte u konzoli sledeće komande:

C:\Program Files (x86)\Microsoft Visual Studio 14.0>cd..

C:\Program Files (x86)>cd..

C:\>cd workspace

C:\Workspace>cd c#

C:\Workspace\c#>cd mymanifest

C:\Workspace\c#\MyManifest>cd mymanifest

C:\Workspace\c#\MyManifest\MyManifest>cd bin

C:\Workspace\c#\MyManifest\MyManifest\bin>cd release

C:\Workspace\c#\MyManifest\MyManifest\bin\Release>ildasm mymanifest.exe

Kad kliknete Enter otvoriće vam se fajl mymanifest.exe u ILDASM alatu. Kliknite na Manifest vašeg sklopa.

 
( Pregled Manifest-a sklopa alatom ILDASM )

Pogledajte meta podatke vašeg sklopa i pod Manifestom ćete videti informacije koje ste promenili.

// Metadata version: v4.0.30319
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 4:0:0:0
}
.assembly MyManifest
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx
                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.

  // --- The following custom attribute is added automatically, do not uncomment -------
  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 )

  .custom instance void [mscorlib]System.Reflection.AssemblyTitleAttribute::.ctor(string) = ( 01 00 0A 4D 79 4D 61 6E 69 66 65 73 74 00 00 )    // ...MyManifest..
  .custom instance void [mscorlib]System.Reflection.AssemblyDescriptionAttribute::.ctor(string) = ( 01 00 00 00 00 )
  .custom instance void [mscorlib]System.Reflection.AssemblyConfigurationAttribute::.ctor(string) = ( 01 00 00 00 00 )
  .custom instance void [mscorlib]System.Reflection.AssemblyCompanyAttribute::.ctor(string) = ( 01 00 12 4D 61 6E 75 65 6C 20 43 6F 72 70 6F 72   // ...Manuel Corpor
                                                                                                61 74 69 6F 6E 00 00 )                            // ation..
  .custom instance void [mscorlib]System.Reflection.AssemblyProductAttribute::.ctor(string) = ( 01 00 0A 4D 79 4D 61 6E 69 66 65 73 74 00 00 )    // ...MyManifest..
  .custom instance void [mscorlib]System.Reflection.AssemblyCopyrightAttribute::.ctor(string) = ( 01 00 25 4D 61 6E 75 65 6C 20 43 6F 72 70 6F 72   // ..%Manuel Corpor
                                                                                                  61 74 69 6F 6E 20 43 6F 70 79 72 69 67 68 74 20   // ation Copyright
                                                                                                  C2 A9 20 20 32 30 31 36 00 00 )                   // ..  2016..
  .custom instance void [mscorlib]System.Reflection.AssemblyTrademarkAttribute::.ctor(string) = ( 01 00 00 00 00 )
  .custom instance void [mscorlib]System.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool) = ( 01 00 00 00 00 )
  .custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = ( 01 00 24 33 64 63 39 64 30 64 38 2D 66 32 37 38   // ..$3dc9d0d8-f278
                                                                                                  2D 34 63 66 62 2D 38 33 34 35 2D 33 30 30 64 38   // -4cfb-8345-300d8
                                                                                                  30 65 34 32 37 31 38 00 00 )                      // 0e42718..
  .custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = ( 01 00 07 31 2E 30 2E 30 2E 30 00 00 )             // ...1.0.0.0..
  .custom instance void [mscorlib]System.Resources.NeutralResourcesLanguageAttribute::.ctor(string) = ( 01 00 05 65 6E 2D 55 53 00 00 )                   // ...en-US..
  .custom instance void [mscorlib]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = ( 01 00 1A 2E 4E 45 54 46 72 61 6D 65 77 6F 72 6B   // ....NETFramework
                                                                                                        2C 56 65 72 73 69 6F 6E 3D 76 34 2E 36 01 00 54   // ,Version=v4.6..T
                                                                                                        0E 14 46 72 61 6D 65 77 6F 72 6B 44 69 73 70 6C   // ..FrameworkDispl
                                                                                                        61 79 4E 61 6D 65 12 2E 4E 45 54 20 46 72 61 6D   // ayName..NET Fram
                                                                                                        65 77 6F 72 6B 20 34 2E 36 )                      // ework 4.6
  .hash algorithm 0x00008004
  .ver 1:0:0:0
}
.module MyManifest.exe
// MVID: {C9685E8E-7AEF-4CCB-8A68-F52C6FF9F247}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00020003    //  ILONLY 32BITPREFERRED
// Image base: 0x024F0000

Vi možete navedene informacije zabeležiti i u posebnu tekstualnu datoteku sledećom naredbom:

ildasm /out:mymanifest.txt mymanifest.exe

Kako sve to izgleda možete pogledati i na video-u:


( C# 6.0 Tutorial - Advanced - 3. Manifest )

Kako da registrujem sklop u GAC – Global Assembly Cashe?


Najbolje da to vidite praktičnim primerom. Prvo ćemo napraviti jedan javni ili deljeni sklop. Znači pokrenite novi projekat, ali ovaj put umesto konzolne aplikacije izaberite šablon Class Library i vašu deljenu datoteku nazovite ClassLibrary, zatim unesite sledeći kod.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ClassLibrary
{
    public class TestClass
    {
        public static string TestMethod => "This is a public or shared assembly.";

    }
}

Kao u prethodnom primeru, otvorite Solution Explorer; kliknite desnim tasterom miša na vaš projekat i u meniju izaberite Properties. Kliknite na dugme Assembly Information i promenite informacije u naziv vaše kompanije ili kompanije kakvu bi ste voleli da imate u budućnosti. Da bi vaš strong namestrong ime bilo u potpunosti određeno, neophodno je da generišete ključ za vaše strong ime. Pređite na tab Signing*, čekirajte opciju Sign the assembly, zatim u ComboBox-u izaberite <New…> i kad vam se otvori forma za unos podataka o ključu, navedite ime ključa kao TestKey, odredite neku vašu šifru, mora imati više od 6 karaktera i izaberite algoritam sha256RSA za vaš ključ.


( Create Strong Name Key forma )

Potvrdite vaš unos, kompajlirajte vaš projekat kao Release i dobićete poruku koja vas obaveštava da vi ne možete direktno pokrenuti vašu datoteku što je očigledno, ali će vaša datoteka biti kompajlirana. Zatvorite vaš projekat. Generisanje vašeg ključa za strong ime ste mogli da uradite i jednostavnije preko alata SN.EXE – strong name; koristeći konzolu sledećom komandom:

sn -k TestKey.snk

Kad ste strong imenovali vaš sklop vi možete samo da referencirate sklopove koji su takođe strong imenovani iz sigurnosnih razloga. Međutim tada možete imati drugi problem. Neko od zaposlenih može kopirati vaš privatni ključ i zato se ključ ne pravi sve do samog puštanja aplikacije u prodaju. Vaš čvrsto imenovani sklop takođe ne garantuje da njegov ključ dolazi od vas. On samo pokazuje da osoba koja je kreirala sklop ima privatni ključ. Zato kompanije koje prave softver koriste Microsoft Authenticode Certificate koji kupe online i plaćaju njegovu validaciju na godišnjem nivou. Otvorite Windows Explorer ili File Explorer, potražite direktorijum ClassLibrary koji ste prethodno napravili. Kad otvorite TestKey fajl u tekst editoru, videćete da je vaš ključ kriptovan sa Microsoft Strong Cryptographic Provider-om. Sad kad imate definisan strong ime za vaš sklop, onda ga možete generisati u GAC - Global Assembly Cache pomoću alata GACUTIL.EXE. S obzirom da su nam potrebna administratorska ovlašćenja Windows operativnog sistema, neophodno je da otvorite Developer Command Prompt kao administrator, tako što će te kliknuti desnim tasterom miša na isti i pokrenuti ga izborom u meniju Run as Administrator. U zavisnosti gde ste usnimili vaš projekat unesite sledeće komande:

C:\WINDOWS\system32>cd..

C:\Windows>cd..

C:\>cd workspace

C:\Workspace>cd c#

C:\Workspace\c#>cd classlibrary

C:\Workspace\c#\ClassLibrary>cd classlibrary

C:\Workspace\c#\ClassLibrary\ClassLibrary>cd bin

C:\Workspace\c#\ClassLibrary\ClassLibrary\bin>cd release

C:\Workspace\c#\ClassLibrary\ClassLibrary\bin\Release>gacutil.exe -i classlibrary.dll

Microsoft (R) .NET Global Assembly Cache Utility. Version 4.0.30319.0
Copyright (c) Microsoft Corporation. All rights reserved.

Assembly successfully added to the cache

C:\Workspace\c#\ClassLibrary\ClassLibrary\bin\Release>


Ukoliko otvorite Windows Explorer ili File Explorer i pogledate direktorijum C:\Windows\Microsoft.NET\assembly\GAC_MSIL\ videćete novi direktorijum C:\Windows\Microsoft.NET\assembly\GAC_MSIL\ClassLibrary\v4.0_1.0.0.0__8c7b556ffba01917 gde je kopirana vaša deljena datoteka classlibrary.dll koju mogu sad da koriste i drugi projekti bez obzira koji .Net programski jezik koristite.


( GAC - Global Assembly Cashe folder )

Jednostavno referencirate datoteku i ona će se iskopirati u vaš projekat. Da bi proverili kako naša navedena datoteka radi, pokrenite nov projekat; konzolnu aplikaciju i nazovite je Gac. Otvorite Solution Explorer i kliknite desnim tasterom miša na direktorijum References, zatim kliknite na Add Reference i preko Reference Manager-a referencirajte classlibrary.dll.


( Reference Manager forma )

Zatim unesite u Main proceduru vaše aplikacije sledeći kod:

using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Gac
{
    class Program
    {
        static void Main(string[] args)
        {
            string test = ClassLibrary.TestClass.TestMethod;
            WriteLine(test);
            WriteLine(Environment.NewLine + "Press any key to continue...");
            ReadKey();
           
        }
    }
}

Pokrenite vašu aplikaciju u Release modu i videćete da vaša aplikacija uspešno koristi deljenu datoteku:

This is a public or shared assembly.

Press any key to continue...


Kako sve to izgleda možete pogledati i na video-u:

 
( C# 6.0 Tutorial - Advanced - 4. Register an assembly in GAC )

Šta su resursi i sklopovi resursa?

Resursi su vam podaci koji se ne mogu izvršavati iako postoje u vašoj aplikaciji. To može biti skup slika ili stringovi prikazani na korisničkom interfejsu poput kulture za posmatrani računar. Smeštanjem podataka u resursne datoteke vi zapravo možete da menjate podatke koje program zahteva, a da pri tome ne morate ponovo da kompajlirate celu aplikaciju. Pre su programeri uglavnom koristili posebnu alatku za pravljenje resursnih datoteka, ResEditor. Sad jednostavno možete dodate vašem projektu šablon Resorce File kao što dodajete i bilo koji drugi šablon u Visual Studio-u i napraviti vlastite resurse za vašu aplikaciju. Poenta je da sklopovi mogu obuhvatati i resursne fajlove. Resursnim fajlovima ćemo se baviti kad za tim imamo potrebu, kao na primer kad vam je potrebno da vaša aplikacija ima ikonicu aplikacije koju vi želite da ima i kad budemo opisali postove kako se podaci čuvaju u datotekama iako nisu baze podataka.

Šta je refleksija?

Refleksija je opšti pojam koji obuhvata razne bazne .Net klase i koji nam omogućavaju da saznamo informacije o tipovima podataka u aplikacijama i drugim sklopovima kao i da pročitamo druge meta podatke iz manifest sklopa. Većina ovih klasa se nalazi u prostoru imena System.Reflection. Pogledajte kod sledećeg programa koji će vam biti jako koristan da očitate polja, konstruktore, propertije i metode bilo kojeg tipa podataka, čak i one koje vi napravite. Pokrenite novu konzolnu aplikaciju i nazovite je Reflection. Unesite sledeći kod, ali obratite pažnju da uvedete imenski prostor System.Reflection.

using System;
using static System.Console;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Reflection
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                string typeName = String.Empty;
                Write("Enter type name: ");
                typeName = ReadLine();

                Type T = Type.GetType(typeName);

                FieldInfo[] fields = T.GetFields();
                WriteLine(Environment.NewLine + "Fields:" + Environment.NewLine);
                foreach (FieldInfo item in fields)
                {
                    WriteLine(item.ReflectedType.Name + " " + item.Name);

                }

                PropertyInfo[] properties = T.GetProperties();
                WriteLine(Environment.NewLine + "Properties:" + Environment.NewLine);
                foreach (PropertyInfo item in properties)
                {
                    WriteLine(item.ReflectedType.Name + " " + item.Name);

                }

                ConstructorInfo[] constructors = T.GetConstructors();
                WriteLine(Environment.NewLine + "Constructors:" + Environment.NewLine);
                foreach (ConstructorInfo item in constructors)
                {
                    WriteLine(item.ReflectedType.Name + " " + item.Name);

                }

                MethodInfo[] methods = T.GetMethods();
                WriteLine(Environment.NewLine + "Methods:" + Environment.NewLine);
                foreach (MethodInfo item in methods)
                {
                    WriteLine(item.ReflectedType.Name + " " + item.Name);

                }
            }
            catch (Exception ex)
            {
                WriteLine(Environment.NewLine + ex.Message);
               
            }

            WriteLine(Environment.NewLine + "Press any key to continue...");
            ReadKey();

        }
    }
}

Pokrenite program i ispitajte bilo koji tip podataka ili na primer System.String. Dobićete sledeće rezultate:

Enter type name: System.String

Fields:

String Empty

Properties:

String Chars
String Length

Constructors:

String .ctor
String .ctor
String .ctor
String .ctor
String .ctor
String .ctor
String .ctor
String .ctor

Methods:

String Join
String Join
String Join
String Join
String Join
String Equals
String Equals
String Equals
String Equals
String Equals
String op_Equality
String op_Inequality
String get_Chars
String CopyTo
String ToCharArray
String ToCharArray
String IsNullOrEmpty
String IsNullOrWhiteSpace
String GetHashCode
String get_Length
String Split
String Split
String Split
String Split
String Split
String Split
String Substring
String Substring
String Trim
String TrimStart
String TrimEnd
String IsNormalized
String IsNormalized
String Normalize
String Normalize
String Compare
String Compare
String Compare
String Compare
String Compare
String Compare
String Compare
String Compare
String Compare
String Compare
String CompareTo
String CompareTo
String CompareOrdinal
String CompareOrdinal
String Contains
String EndsWith
String EndsWith
String EndsWith
String IndexOf
String IndexOf
String IndexOf
String IndexOfAny
String IndexOfAny
String IndexOfAny
String IndexOf
String IndexOf
String IndexOf
String IndexOf
String IndexOf
String IndexOf
String LastIndexOf
String LastIndexOf
String LastIndexOf
String LastIndexOfAny
String LastIndexOfAny
String LastIndexOfAny
String LastIndexOf
String LastIndexOf
String LastIndexOf
String LastIndexOf
String LastIndexOf
String LastIndexOf
String PadLeft
String PadLeft
String PadRight
String PadRight
String StartsWith
String StartsWith
String StartsWith
String ToLower
String ToLower
String ToLowerInvariant
String ToUpper
String ToUpper
String ToUpperInvariant
String ToString
String ToString
String Clone
String Trim
String Insert
String Replace
String Replace
String Remove
String Remove
String Format
String Format
String Format
String Format
String Format
String Format
String Format
String Format
String Copy
String Concat
String Concat
String Concat
String Concat
String Concat
String Concat
String Concat
String Concat
String Concat
String Concat
String Concat
String Intern
String IsInterned
String GetTypeCode
String GetEnumerator
String GetType

Press any key to continue...


Jednostavno možete videti sva polja, konstruktore, propertije i metode tipa System.String. Kako navedeni program izgleda možete pogledati i na video-u:


( C# 6.0 Tutorial - Advanced - 5. Reflection )
  

No comments:

Post a Comment