Jazyková nezávislost a jazykově nezávislé komponentyLanguage Independence and Language-Independent Components

.NET Framework je nezávislý na jazyce.The .NET Framework is language independent. To znamená, že jako vývojář můžete vyvíjet v jednom z mnoha jazyků, které cílí na .NET Framework, C#jako jsou například C++/CLI, Eiffel, F#, ironpythonu, IronRuby, PowerBuilder, Visual Basic, Visual COBOL a Windows PowerShell.This means that, as a developer, you can develop in one of the many languages that target the .NET Framework, such as C#, C++/CLI, Eiffel, F#, IronPython, IronRuby, PowerBuilder, Visual Basic, Visual COBOL, and Windows PowerShell. Můžete získat přístup k typům a členům knihoven tříd vyvinutých pro .NET Framework bez nutnosti znát jazyk, ve kterém byly původně zapsány, a nemusíte přitom dodržovat žádnou z původních konvencí jazyka.You can access the types and members of class libraries developed for the .NET Framework without having to know the language in which they were originally written and without having to follow any of the original language's conventions. Pokud jste vývojář komponent, k vaší komponentě se dá dostat z aplikace .NET Framework bez ohledu na jeho jazyk.If you are a component developer, your component can be accessed by any .NET Framework app regardless of its language.

Poznámka

Tato první část tohoto článku popisuje vytváření komponent nezávislých na jazyce – to znamená komponenty, které mohou být spotřebovány aplikacemi, které jsou napsané v libovolném jazyce.This first part of this article discusses creating language-independent components—that is, components that can be consumed by apps that are written in any language. Můžete také vytvořit jednu komponentu nebo aplikaci ze zdrojového kódu napsaného v několika jazycích. viz interoperabilita mezi jazyky v druhé části tohoto článku.You can also create a single component or app from source code written in multiple languages; see Cross-Language Interoperability in the second part of this article.

Aby bylo možné plně spolupracovat s jinými objekty napsanými v libovolném jazyce, musí tyto objekty zveřejnit volajícím pouze ty funkce, které jsou společné pro všechny jazyky.To fully interact with other objects written in any language, objects must expose to callers only those features that are common to all languages. Tato společná sada funkcí je definována specifikací CLS (Common Language Specification), což je sada pravidel, která se vztahují na generovaná sestavení.This common set of features is defined by the Common Language Specification (CLS), which is a set of rules that apply to generated assemblies. Specifikace CLS (Common Language Specification) je definována v oddílu I klauzule 7 až 11 ze standardu ECMA-335: Common Language Infrastructure.The Common Language Specification is defined in Partition I, Clauses 7 through 11 of the ECMA-335 Standard: Common Language Infrastructure.

Pokud vaše komponenta odpovídá specifikaci CLS (Common Language Specification), je zaručena, že je kompatibilní se specifikací CLS a je možné k nim přicházet z kódu v sestaveních napsaných v jakémkoli programovacím jazyce, který podporuje specifikaci CLS.If your component conforms to the Common Language Specification, it is guaranteed to be CLS-compliant and can be accessed from code in assemblies written in any programming language that supports the CLS. Můžete určit, zda vaše komponenta odpovídá specifikaci CLS (Common Language Specification) v době kompilace, použitím atributu CLSCompliantAttribute pro váš zdrojový kód.You can determine whether your component conforms to the Common Language Specification at compile time by applying the CLSCompliantAttribute attribute to your source code. Další informace najdete v atributu CLSCompliantAttribute.For more information, see The CLSCompliantAttribute attribute.

V tomto článku:In this article:

Pravidla dodržování předpisů CLSCLS compliance rules

Tato část popisuje pravidla pro vytvoření komponenty kompatibilní se specifikací CLS.This section discusses the rules for creating a CLS-compliant component. Úplný seznam pravidel naleznete v oddílu I klauzule 11 ve standardu ECMA-335: Common Language Infrastructure.For a complete list of rules, see Partition I, Clause 11 of the ECMA-335 Standard: Common Language Infrastructure.

Poznámka

Specifikace CLS (Common Language Specification) se zabývá všemi pravidly dodržování specifikace CLS, protože se vztahuje na příjemce (vývojáři, kteří mají programově přístup k komponentě, která je kompatibilní se specifikací CLS), architektury (vývojáři, kteří používají kompilátor jazyka k vytvoření Knihovny kompatibilní se specifikací CLS) a zařízení (vývojáři, kteří vytvářejí nástroj, jako je například kompilátor jazyka nebo analyzátor kódu, který vytváří komponenty kompatibilní se specifikací CLS).The Common Language Specification discusses each rule for CLS compliance as it applies to consumers (developers who are programmatically accessing a component that is CLS-compliant), frameworks (developers who are using a language compiler to create CLS-compliant libraries), and extenders (developers who are creating a tool such as a language compiler or a code parser that creates CLS-compliant components). Tento článek se zaměřuje na pravidla, která se vztahují na rozhraní.This article focuses on the rules as they apply to frameworks. Všimněte si ale, že některá pravidla, která platí pro rozšířené, mohou platit také pro sestavení, která jsou vytvořena pomocí reflexe. Emit.Note, though, that some of the rules that apply to extenders may also apply to assemblies that are created using Reflection.Emit.

Chcete-li navrhnout komponentu, která je nezávislá na jazyce, stačí použít pravidla pro dodržování specifikace CLS pro veřejné rozhraní vaší komponenty.To design a component that is language independent, you only need to apply the rules for CLS compliance to your component's public interface. Vaše soukromá implementace nemusí odpovídat specifikaci.Your private implementation does not have to conform to the specification.

Důležité

Pravidla pro dodržování předpisů CLS platí pouze pro veřejné rozhraní komponenty, nikoli na jeho soukromou implementaci.The rules for CLS compliance apply only to a component's public interface, not to its private implementation.

Například celá čísla bez znaménka jiná než Byte nejsou kompatibilní se specifikací CLS.For example, unsigned integers other than Byte are not CLS-compliant. Vzhledem k tomu, že třída Person v následujícím příkladu zpřístupňuje vlastnost Age typu UInt16, následující kód zobrazí upozornění kompilátoru.Because the Person class in the following example exposes an Age property of type UInt16, the following code displays a compiler warning.

using System;

[assembly: CLSCompliant(true)]

public class Person
{
   private UInt16 personAge = 0;

   public UInt16 Age 
   { get { return personAge; } }
}
// The attempt to compile the example displays the following compiler warning:
//    Public1.cs(10,18): warning CS3003: Type of 'Person.Age' is not CLS-compliant
<Assembly: CLSCompliant(True)> 

Public Class Person
   Private personAge As UInt16
   
   Public ReadOnly Property Age As UInt16
      Get
         Return personAge      
      End Get   
   End Property
End Class
' The attempt to compile the example displays the following compiler warning:
'    Public1.vb(9) : warning BC40027: Return type of function 'Age' is not CLS-compliant.
'    
'       Public ReadOnly Property Age As UInt16
'                                ~~~

Třídu Person kompatibilní se specifikací CLS můžete nastavit tak, že změníte typ Age vlastnosti z UInt16 na Int16, což je 16bitové podepsané celé číslo kompatibilní se specifikací CLS.You can make the Person class CLS-compliant by changing the type of Age property from UInt16 to Int16, which is a CLS-compliant, 16-bit signed integer. Nemusíte měnit typ pole private personAge.You do not have to change the type of the private personAge field.

using System;

[assembly: CLSCompliant(true)]

public class Person
{
   private Int16 personAge = 0;

   public Int16 Age 
   { get { return personAge; } }
}
<Assembly: CLSCompliant(True)> 

Public Class Person
   Private personAge As UInt16
   
   Public ReadOnly Property Age As Int16
      Get
         Return CType(personAge, Int16)      
      End Get   
   End Property
End Class

Veřejné rozhraní knihovny se skládá z následujících:A library's public interface consists of the following:

  • Definice veřejných tříd.Definitions of public classes.

  • Definice veřejných členů veřejných tříd a definice členů přístupných k odvozeným třídám (tj. chráněným členům).Definitions of the public members of public classes, and definitions of members accessible to derived classes (that is, protected members).

  • Parametry a návratové typy veřejných tříd a parametry a návratové typy metod, které jsou přístupné pro odvozené třídy.Parameters and return types of public methods of public classes, and parameters and return types of methods accessible to derived classes.

Pravidla pro dodržování specifikace CLS jsou uvedená v následující tabulce.The rules for CLS compliance are listed in the following table. Text pravidel se bere v platnost od standardu ECMA-335: Common Language Infrastructure, což je Copyright 2012 podle Ecma International.The text of the rules is taken verbatim from the ECMA-335 Standard: Common Language Infrastructure, which is Copyright 2012 by Ecma International. Podrobnější informace o těchto pravidlech najdete v následujících oddílech.More detailed information about these rules is found in the following sections.

KategorieCategory Další informace naleznete v tématuSee PravidloRule Číslo pravidlaRule number
UsnadněníAccessibility Přístupnost členaMember accessibility Při přepisu zděděných metod se přístupnost nemění, s výjimkou přepsání metody zděděné z jiného sestavení s přístupností family-or-assembly.Accessibility shall not be changed when overriding inherited methods, except when overriding a method inherited from a different assembly with accessibility family-or-assembly. V takovém případě má přepsání přístup family.In this case, the override shall have accessibility family. 10pruhový10
UsnadněníAccessibility Přístupnost členaMember accessibility Viditelnost a přístupnost typů a členů musí být takové, aby typy v signatuře kteréhokoli člena byly viditelné a přístupné, kdykoli je samotný člen viditelný a přístupný.The visibility and accessibility of types and members shall be such that types in the signature of any member shall be visible and accessible whenever the member itself is visible and accessible. Například veřejná metoda, která je viditelná vně sestavení, nesmí obsahovat argument, jehož typ je viditelný pouze v rámci sestavení.For example, a public method that is visible outside its assembly shall not have an argument whose type is visible only within the assembly. Viditelnost a přístupnost typů tvořících instanci obecného typu používaného v podpisu každého člena musí být viditelná a přístupná, kdykoli je samotný člen viditelný a přístupný.The visibility and accessibility of types composing an instantiated generic type used in the signature of any member shall be visible and accessible whenever the member itself is visible and accessible. Například instance obecného typu přítomná v signatuře člena, který je viditelný mimo jeho sestavení, nesmí mít obecný argument, jehož typ je viditelný pouze v rámci sestavení.For example, an instantiated generic type present in the signature of a member that is visible outside its assembly shall not have a generic argument whose type is visible only within the assembly. 12,512
PoleArrays PoleArrays Pole musí mít prvky s typem odpovídajícím specifikaci CLS a všechny dimenze pole musí mít nižší meze nula.Arrays shall have elements with a CLS-compliant type, and all dimensions of the array shall have lower bounds of zero. Pouze skutečnost, že položka je pole a typ elementu pole musí být požadován pro rozlišení mezi přetíženími.Only the fact that an item is an array and the element type of the array shall be required to distinguish between overloads. Pokud je přetížení založeno na dvou nebo více typech pole, musí být typy prvků pojmenované typy.When overloading is based on two or more array types the element types shall be named types. 16bitovém16
AtributyAttributes AtributyAttributes Atributy musí být typu System.Attributenebo typu, který z něj dědí.Attributes shall be of type System.Attribute, or a type inheriting from it. 4141
AtributyAttributes AtributyAttributes Specifikace CLS umožňuje pouze podmnožinu kódování pro vlastní atributy.The CLS only allows a subset of the encodings of custom attributes. Jediné typy, které se zobrazí v těchto kódováních jsou (viz oddíl IV): System.Type, System.String, System.Char, System.Boolean, System.Byte, System.Int16, System.Int32, System.Int64, System.Single, System.Doublea jakýkoli typ výčtu založený na typu základního typu Integer kompatibilní se specifikací CLS.The only types that shall appear in these encodings are (see Partition IV): System.Type, System.String, System.Char, System.Boolean, System.Byte, System.Int16, System.Int32, System.Int64, System.Single, System.Double, and any enumeration type based on a CLS-compliant base integer type. 3434
AtributyAttributes AtributyAttributes Specifikace CLS neumožňuje veřejně viditelné požadované modifikátory (modreq, viz oddíl II), ale umožňuje volitelné modifikátory (modopt, viz oddíl II), které nerozumí.The CLS does not allow publicly visible required modifiers (modreq, see Partition II), but does allow optional modifiers (modopt, see Partition II) it does not understand. 3535
KonstruktoryConstructors KonstruktoryConstructors Konstruktor objektu musí volat konstruktor instance své základní třídy před jakýmkoli přístupem k zděděným datům instance.An object constructor shall call some instance constructor of its base class before any access occurs to inherited instance data. (To se nevztahuje na typy hodnot, které nemusí mít konstruktory.)(This does not apply to value types, which need not have constructors.) 2021
KonstruktoryConstructors KonstruktoryConstructors Konstruktor objektu se nesmí volat kromě v rámci vytváření objektu a objekt se nemůže inicializovat dvakrát.An object constructor shall not be called except as part of the creation of an object, and an object shall not be initialized twice. 2222
VýčtyEnumerations VýčtyEnumerations Nadřazený typ výčtu musí být vestavěný celočíselný typ CLS, název pole musí být "value__" a toto pole musí být označeno jako RTSpecialName.The underlying type of an enum shall be a built-in CLS integer type, the name of the field shall be "value__", and that field shall be marked RTSpecialName. čl7
VýčtyEnumerations VýčtyEnumerations Existují dva různé druhy výčtů, které jsou označeny přítomností nebo absence System.FlagsAttribute (viz oddíl IV knihovna) vlastní atribut.There are two distinct kinds of enums, indicated by the presence or absence of the System.FlagsAttribute (see Partition IV Library) custom attribute. Jedna představuje pojmenované celočíselné hodnoty; druhý představuje pojmenované bitové příznaky, které lze kombinovat pro vygenerování nepojmenované hodnoty.One represents named integer values; the other represents named bit flags that can be combined to generate an unnamed value. Hodnota enum není omezena na zadané hodnoty.The value of an enum is not limited to the specified values. 88
VýčtyEnumerations VýčtyEnumerations Literální statická pole výčtového typu musí mít typ samotného výčtu.Literal static fields of an enum shall have the type of the enum itself. 99
UdálostiEvents UdálostiEvents Metody, které implementují událost, musí být označené SpecialName v metadatech.The methods that implement an event shall be marked SpecialName in the metadata. 2929
UdálostiEvents UdálostiEvents Přístupnost události a jejích přistupujících objektů se musí shodovat.The accessibility of an event and of its accessors shall be identical. 3030
UdálostiEvents UdálostiEvents Metody add a remove události musí být buď přítomny, nebo chybět.The add and remove methods for an event shall both either be present or absent. čl31
UdálostiEvents UdálostiEvents Metody add a remove pro událost musí mít jeden parametr, jehož typ Určuje typ události a který musí být odvozen od System.Delegate.The add and remove methods for an event shall each take one parameter whose type defines the type of the event and that shall be derived from System.Delegate. 3232
UdálostiEvents UdálostiEvents Události musí dodržovat konkrétní vzor pojmenování.Events shall adhere to a specific naming pattern. Atribut SpecialName, na který odkazuje pravidlo specifikace CLS 29, se ignoruje v odpovídajících porovnáních názvů a musí splňovat pravidla identifikátorů.The SpecialName attribute referred to in CLS rule 29 shall be ignored in appropriate name comparisons and shall adhere to identifier rules. 3333
VýjimkyExceptions VýjimkyExceptions Objekty, které jsou vyvolány, musí být typu System.Exception nebo typu, který z něj dědí.Objects that are thrown shall be of type System.Exception or a type inheriting from it. Nicméně metody kompatibilní se specifikací CLS nejsou požadovány pro blokování šíření jiných typů výjimek.Nonetheless, CLS-compliant methods are not required to block the propagation of other types of exceptions. 4040
ObecnéGeneral Kompatibilita se specifikací CLS: pravidlaCLS compliance: the Rules Pravidla CLS se vztahují pouze na ty části typu, které jsou přístupné nebo viditelné mimo definiční sestavení.CLS rules apply only to those parts of a type that are accessible or visible outside of the defining assembly. první1
ObecnéGeneral Kompatibilita se specifikací CLS: pravidlaCLS compliance: the Rules Členy typů, které nejsou kompatibilní se specifikací CLS, nesmí být označeny jako kompatibilní se specifikací CLS.Members of non-CLS compliant types shall not be marked CLS-compliant. odst2
Obecné typyGenerics Obecné typy a členyGeneric types and members Vnořené typy musí mít alespoň tolik obecných parametrů jako nadřazený typ.Nested types shall have at least as many generic parameters as the enclosing type. Obecné parametry ve vnořeném typu odpovídají umístění obecným parametrům v nadřazeném typu.Generic parameters in a nested type correspond by position to the generic parameters in its enclosing type. 4242
Obecné typyGenerics Obecné typy a členyGeneric types and members Název obecného typu musí kódovat počet parametrů typu deklarovaných pro nevnořený typ, nebo nově zavedený na typ, pokud je vnořený, podle pravidel definovaných výše.The name of a generic type shall encode the number of type parameters declared on the non-nested type, or newly introduced to the type if nested, according to the rules defined above. 4343
Obecné typyGenerics Obecné typy a členyGeneric types and members Obecný typ musí znovu deklarovat dostatečná omezení, aby bylo zaručeno, že jakákoli omezení základního typu nebo rozhraní budou splněna omezeními obecného typu.A generic type shall redeclare sufficient constraints to guarantee that any constraints on the base type, or interfaces would be satisfied by the generic type constraints. 44444444
Obecné typyGenerics Obecné typy a členyGeneric types and members Typy, které se používají jako omezení u obecných parametrů, samy o nich vyhovují specifikaci CLS.Types used as constraints on generic parameters shall themselves be CLS-compliant. 4545
Obecné typyGenerics Obecné typy a členyGeneric types and members Viditelnost a přístupnost členů (včetně vnořených typů) v instanci generického typu se považují za obor pro konkrétní instanci, nikoli jako deklaraci obecného typu jako celku.The visibility and accessibility of members (including nested types) in an instantiated generic type shall be considered to be scoped to the specific instantiation rather than the generic type declaration as a whole. Za předpokladu, že pravidla viditelnosti a přístupnosti pravidla CLS 12 budou nadále platit.Assuming this, the visibility and accessibility rules of CLS rule 12 still apply. 4646
Obecné typyGenerics Obecné typy a členyGeneric types and members Pro každou abstraktní nebo virtuální obecnou metodu musí být použita výchozí konkrétní (neabstraktní) implementace.For each abstract or virtual generic method, there shall be a default concrete (non-abstract) implementation. 4747
RozhraníInterfaces RozhraníInterfaces Rozhraní kompatibilní se specifikací CLS nesmí vyžadovat definici metod nekompatibilních se specifikací CLS, aby je bylo možné implementovat.CLS-compliant interfaces shall not require the definition of non-CLS compliant methods in order to implement them. let18
RozhraníInterfaces RozhraníInterfaces Rozhraní kompatibilní se specifikací CLS nesmějí definovat statické metody ani definovat pole.CLS-compliant interfaces shall not define static methods, nor shall they define fields. čl19
ČlenovéMembers Obecné typy členůType members in general Globální statická pole a metody nejsou kompatibilní se specifikací CLS.Global static fields and methods are not CLS-compliant. 3636
ČlenovéMembers -- Hodnota statického literálu je určena pomocí inicializačních metadat pole.The value of a literal static is specified through the use of field initialization metadata. Literál kompatibilní se specifikací CLS musí mít zadanou hodnotu v metadatech inicializace pole, která je přesně stejného typu jako literál (nebo základního typu, pokud je tento literál enum).A CLS-compliant literal must have a value specified in field initialization metadata that is of exactly the same type as the literal (or of the underlying type, if that literal is an enum). 13,513
ČlenovéMembers Obecné typy členůType members in general Omezení vararg není součástí specifikace CLS a jediná konvence volání podporovaná specifikací CLS je standardní spravovaná konvence volání.The vararg constraint is not part of the CLS, and the only calling convention supported by the CLS is the standard managed calling convention. 1515
Zásady vytváření názvůNaming conventions Zásady vytváření názvůNaming conventions Sestavení se řídí podle přílohy 7 technické sestavy 15 sady Unicode Standard 3.0, která se řídí sadou znaků povolených ke spuštění, a jejich zahrnutí do identifikátorů, které jsou k dispozici online na https://www.unicode.org/unicode/reports/tr15/tr15-18.html.Assemblies shall follow Annex 7 of Technical Report 15 of the Unicode Standard3.0 governing the set of characters permitted to start and be included in identifiers, available online at https://www.unicode.org/unicode/reports/tr15/tr15-18.html. Identifikátory musí být v kanonickém formátu definovaném formulářem normalizace Unicode C. Pro účely specifikace CLS jsou dva identifikátory stejné, pokud mapování malých písmen (podle specifikace národního prostředí Unicode rozlišuje malá a velká písmena), jsou stejná.Identifiers shall be in the canonical format defined by Unicode Normalization Form C. For CLS purposes, two identifiers are the same if their lowercase mappings (as specified by the Unicode locale-insensitive, one-to-one lowercase mappings) are the same. To znamená, že u dvou identifikátorů, které se považují za odlišné v rámci specifikace CLS, se liší ve více než pouhém případě.That is, for two identifiers to be considered different under the CLS they shall differ in more than simply their case. Chcete-li však přepsat zděděnou definici, rozhraní příkazového řádku vyžaduje použití přesného kódování původní deklarace.However, in order to override an inherited definition the CLI requires the precise encoding of the original declaration be used. 44
PřetíženíOverloading Zásady vytváření názvůNaming conventions Všechny názvy zavedené v oboru kompatibilním se specifikací CLS musí být nezávislé na druhu, s výjimkou případů, kdy jsou názvy identické a vyřešeny pomocí přetížení.All names introduced in a CLS-compliant scope shall be distinct independent of kind, except where the names are identical and resolved via overloading. To znamená, že zatímco CTSallows jeden typ pro použití stejného názvu pro metodu a pole, specifikace CLS nikoli.That is, while the CTSallows a single type to use the same name for a method and a field, the CLS does not. 55
PřetíženíOverloading Zásady vytváření názvůNaming conventions Pole a vnořené typy se liší podle porovnání identifikátorů, i když CTS umožňuje odlišit jedinečné podpisy.Fields and nested types shall be distinct by identifier comparison alone, even though the CTS allows distinct signatures to be distinguished. Metody, vlastnosti a události, které mají stejný název (podle porovnání identifikátorů), se liší o více než pouze návratovým typem, s výjimkou zadání v pravidle specifikace CLS 39.Methods, properties, and events that have the same name (by identifier comparison) shall differ by more than just the return type,except as specified in CLS Rule 39. 66
PřetíženíOverloading OverloadsOverloads Pouze vlastnosti a metody mohou být přetíženy.Only properties and methods can be overloaded. 3737
PřetíženíOverloading OverloadsOverloads Vlastnosti a metody mohou být přetíženy pouze na základě počtu a typů parametrů, s výjimkou operátorů převodu s názvem op_Implicit a op_Explicit, které mohou být také přetíženy na základě jejich návratového typu.Properties and methods can be overloaded based only on the number and types of their parameters, except the conversion operators named op_Implicit and op_Explicit, which can also be overloaded based on their return type. 3838
PřetíženíOverloading -- Pokud dva nebo více metod odpovídajících specifikaci CLS mají stejný název a pro konkrétní sadu instancí typu, mají stejný parametr a návratové typy, pak všechny tyto metody musí být sémanticky rovnocenné v těchto instancích typu.If two or more CLS-compliant methods declared in a type have the same name and, for a specific set of type instantiations, they have the same parameter and return types, then all these methods shall be semantically equivalent at those type instantiations. 4848
TypyTypes Typ a signatury členů typuType and type member signatures System.Object je kompatibilní se specifikací CLS.System.Object is CLS-compliant. Všechny ostatní třídy odpovídající specifikaci CLS dědí z třídy kompatibilní se specifikací CLS.Any other CLS-compliant class shall inherit from a CLS-compliant class. listopadu23
VlastnostiProperties VlastnostiProperties Metody, které implementují metody getter a setter vlastnosti, musí být označeny SpecialName v metadatech.The methods that implement the getter and setter methods of a property shall be marked SpecialName in the metadata. 2424
VlastnostiProperties VlastnostiProperties Přistupující objekty vlastnosti musí být všechny statické, všechny virtuální nebo všechny instance.A property’s accessors shall all be static, all be virtual, or all be instance. 2626
VlastnostiProperties VlastnostiProperties Typ vlastnosti musí být návratový typ getter a typ posledního argumentu setter.The type of a property shall be the return type of the getter and the type of the last argument of the setter. Typy parametrů vlastnosti musí být typy parametrů pro metodu getter a typy všech, ale konečný parametr metody setter.The types of the parameters of the property shall be the types of the parameters to the getter and the types of all but the final parameter of the setter. Všechny tyto typy musí být kompatibilní se specifikací CLS a nesmí být spravované ukazatele (tj. nesmí být předány odkazem).All of these types shall be CLS-compliant, and shall not be managed pointers (i.e., shall not be passed by reference). dlouhý27
VlastnostiProperties VlastnostiProperties Vlastnosti musí splňovat konkrétní vzor pojmenování.Properties shall adhere to a specific naming pattern. Atribut SpecialName, na který se odkazuje v pravidle CLS 24, se ignoruje v odpovídajících porovnáních názvů a musí splňovat pravidla identifikátoru.The SpecialName attribute referred to in CLS rule 24 shall be ignored in appropriate name comparisons and shall adhere to identifier rules. Vlastnost musí mít metodu getter, metodu setter nebo obojí.A property shall have a getter method, a setter method, or both. 2828
Převod typuType conversion Převod typuType conversion Pokud je k dispozici buď op_Implicit, nebo op_Explicit, je k dispozici alternativní způsob poskytnutí tohoto vynucení.If either op_Implicit or op_Explicit is provided, an alternate means of providing the coercion shall be provided. 3939
TypyTypes Typ a signatury členů typuType and type member signatures Typy zabalené hodnoty nejsou kompatibilní se specifikací CLS.Boxed value types are not CLS-compliant. 33
TypyTypes Typ a signatury členů typuType and type member signatures Všechny typy, které se zobrazují v signatuře, musí být kompatibilní se specifikací CLS.All types appearing in a signature shall be CLS-compliant. Všechny typy tvořící vytvořená instance obecného typu musí být kompatibilní se specifikací CLS.All types composing an instantiated generic type shall be CLS-compliant. odst11
TypyTypes Typ a signatury členů typuType and type member signatures Typové odkazy nejsou kompatibilní se specifikací CLS.Typed references are not CLS-compliant. čtrnáct14
TypyTypes Typ a signatury členů typuType and type member signatures Nespravované typy ukazatelů nejsou kompatibilní se specifikací CLS.Unmanaged pointer types are not CLS-compliant. sedmnáct17
TypyTypes Typ a signatury členů typuType and type member signatures Třídy kompatibilní se specifikací CLS, typy hodnot a rozhraní nevyžadují implementaci členů neodpovídajících specifikaci CLS.CLS-compliant classes, value types, and interfaces shall not require the implementation of non-CLS-compliant members. 20o20

Typy a signatury členů typuTypes and type member signatures

Typ System.Object je kompatibilní se specifikací CLS a je základní typ všech typů objektů v systému .NET Framework typů.The System.Object type is CLS-compliant and is the base type of all object types in the .NET Framework type system. Dědičnost v .NET Framework je buď implicitní (například třída String implicitně dědí z třídy Object) nebo explicitní (například třída CultureNotFoundException explicitně dědí z třídy ArgumentException, která explicitně dědí z SystemException třída, která explicitně dědí z Exception třídy).Inheritance in the .NET Framework is either implicit (for example, the String class implicitly inherits from the Object class) or explicit (for example, the CultureNotFoundException class explicitly inherits from the ArgumentException class, which explicitly inherits from the SystemException class, which explicitly inherits from the Exception class). Aby byl odvozený typ kompatibilní se specifikací CLS, musí být jeho základní typ také kompatibilní se specifikací CLS.For a derived type to be CLS compliant, its base type must also be CLS-compliant.

Následující příklad ukazuje odvozený typ, jehož základní typ není kompatibilní se specifikací CLS.The following example shows a derived type whose base type is not CLS-compliant. Definuje základní třídu Counter, která jako čítač používá celé číslo bez znaménka 32-bit.It defines a base Counter class that uses an unsigned 32-bit integer as a counter. Vzhledem k tomu, že třída poskytuje funkce čítače tím, že zabalí unsigned integer, třída je označena jako nekompatibilní se specifikací CLS.Because the class provides counter functionality by wrapping an unsigned integer, the class is marked as non-CLS-compliant. V důsledku toho odvozená třída, NonZeroCounter, není kompatibilní se specifikací CLS.As a result, a derived class, NonZeroCounter, is also not CLS-compliant.

using System;

[assembly: CLSCompliant(true)]

[CLSCompliant(false)] 
public class Counter
{
   UInt32 ctr;
   
   public Counter()
   {
      ctr = 0;
   }
   
   protected Counter(UInt32 ctr)
   {
      this.ctr = ctr;
   }
   
   public override string ToString()
   {
      return String.Format("{0}). ", ctr);
   }

   public UInt32 Value
   {
      get { return ctr; }
   }
   
   public void Increment() 
   {
      ctr += (uint) 1;
   }
}

public class NonZeroCounter : Counter
{
   public NonZeroCounter(int startIndex) : this((uint) startIndex)
   {
   }
   
   private NonZeroCounter(UInt32 startIndex) : base(startIndex)
   {
   }
}
// Compilation produces a compiler warning like the following:
//    Type3.cs(37,14): warning CS3009: 'NonZeroCounter': base type 'Counter' is not
//            CLS-compliant
//    Type3.cs(7,14): (Location of symbol related to previous warning)
<Assembly: CLSCompliant(True)>

<CLSCompliant(False)> _ 
Public Class Counter
   Dim ctr As UInt32
   
   Public Sub New
      ctr = 0
   End Sub
   
   Protected Sub New(ctr As UInt32)
      ctr = ctr
   End Sub
   
   Public Overrides Function ToString() As String
      Return String.Format("{0}). ", ctr)
   End Function

   Public ReadOnly Property Value As UInt32
      Get
         Return ctr
      End Get
   End Property
   
   Public Sub Increment()
      ctr += CType(1, UInt32)
   End Sub
End Class

Public Class NonZeroCounter : Inherits Counter
   Public Sub New(startIndex As Integer)
      MyClass.New(CType(startIndex, UInt32))
   End Sub
   
   Private Sub New(startIndex As UInt32)
      MyBase.New(CType(startIndex, UInt32))
   End Sub
End Class
' Compilation produces a compiler warning like the following:
'    Type3.vb(34) : warning BC40026: 'NonZeroCounter' is not CLS-compliant 
'    because it derives from 'Counter', which is not CLS-compliant.
'    
'    Public Class NonZeroCounter : Inherits Counter
'                 ~~~~~~~~~~~~~~

Všechny typy, které se zobrazují v podpisech členů, včetně návratového typu metody nebo typu vlastnosti, musí být kompatibilní se specifikací CLS.All types that appear in member signatures, including a method's return type or a property type, must be CLS-compliant. Kromě toho pro obecné typy:In addition, for generic types:

  • Všechny typy, které tvoří obecný typ s instancemi, musí být kompatibilní se specifikací CLS.All types that compose an instantiated generic type must be CLS-compliant.

  • Všechny typy použité jako omezení u obecných parametrů musí být kompatibilní se specifikací CLS.All types used as constraints on generic parameters must be CLS-compliant.

.NET Framework běžný typ systému obsahuje řadu předdefinovaných typů, které jsou podporovány přímo modulem CLR (Common Language Runtime) a jsou speciálně kódovány v metadatech sestavení.The .NET Framework common type system includes a number of built-in types that are supported directly by the common language runtime and are specially encoded in an assembly's metadata. Z těchto vnitřních typů jsou typy uvedené v následující tabulce kompatibilní se specifikací CLS.Of these intrinsic types, the types listed in the following table are CLS-compliant.

Typ kompatibilní se specifikací CLSCLS-compliant type PopisDescription
Byte 8 bitů unsigned integer8-bit unsigned integer
Int16 16bitové celé číslo se znaménkem16-bit signed integer
Int32 32 – celé číslo se znaménkem32-bit signed integer
Int64 64 – celé číslo se znaménkem64-bit signed integer
Single Hodnota s plovoucí desetinnou čárkou s jednoduchou přesnostíSingle-precision floating-point value
Double Hodnota s plovoucí desetinnou čárkou s dvojitou přesnostíDouble-precision floating-point value
Boolean Typ hodnoty true nebo falsetrue or false value type
Char Jednotka kódovaného kódu UTF-16UTF-16 encoded code unit
Decimal Desítkové číslo jiné než plovoucí desetinné čárkyNon-floating-point decimal number
IntPtr Ukazatel nebo popisovač velikosti platformy definované platformouPointer or handle of a platform-defined size
String Kolekce nula, jedna nebo více Char objektůCollection of zero, one, or more Char objects

Vnitřní typy uvedené v následující tabulce nejsou kompatibilní se specifikací CLS.The intrinsic types listed in the following table are not CLS-Compliant.

Neodpovídající typNon-compliant type PopisDescription Alternativa odpovídající specifikaci CLSCLS-compliant alternative
SByte 8bitový datový typ se znaménkem na 8bitové číslo8-bit signed integer data type Int16
TypedReference Ukazatel na objekt a jeho typ modulu runtimePointer to an object and its runtime type ŽádnéNone
UInt16 16bitové unsigned integer16-bit unsigned integer Int32
UInt32 32 – bitová unsigned integer32-bit unsigned integer Int64
UInt64 64 – bitová unsigned integer64-bit unsigned integer Int64 (může přetečení), BigIntegernebo DoubleInt64 (may overflow), BigInteger, or Double
UIntPtr Nepodepsaný ukazatel nebo popisovačUnsigned pointer or handle IntPtr

Knihovna tříd .NET Framework nebo jiná knihovna tříd může obsahovat jiné typy, které nejsou kompatibilní se specifikací CLS; například:The .NET Framework Class Library or any other class library may include other types that aren't CLS-compliant; for example:

  • Zabalené typy hodnot.Boxed value types. Následující C# příklad vytvoří třídu, která má veřejnou vlastnost typu int* s názvem Value.The following C# example creates a class that has a public property of type int* named Value. Vzhledem k tomu, že int* je zabalený typ hodnoty, kompilátor jej označí jako nekompatibilní se specifikací CLS.Because an int* is a boxed value type, the compiler flags it as non-CLS-compliant.

    using System;
    
    [assembly:CLSCompliant(true)]
    
    public unsafe class TestClass
    {
       private int* val;
       
       public TestClass(int number)
       {
          val = (int*) number;
       }
    
       public int* Value {
          get { return val; }        
       }
    }
    // The compiler generates the following output when compiling this example:
    //        warning CS3003: Type of 'TestClass.Value' is not CLS-compliant
    
  • Typové odkazy, což jsou speciální konstrukce, které obsahují odkaz na objekt a odkaz na typ.Typed references, which are special constructs that contain a reference to an object and a reference to a type. Typové odkazy jsou reprezentovány v .NET Framework třídou TypedReference.Typed references are represented in the .NET Framework by the TypedReference class.

Pokud typ není kompatibilní se specifikací CLS, měli byste použít atribut CLSCompliantAttribute s hodnotou isCompliant false na ni.If a type is not CLS-compliant, you should apply the CLSCompliantAttribute attribute with an isCompliant value of false to it. Další informace najdete v části atributu CLSCompliantAttribute .For more information, see The CLSCompliantAttribute attribute section.

Následující příklad ilustruje problém dodržování specifikace CLS v signatuře metody a při vytváření instancí obecného typu.The following example illustrates the problem of CLS compliance in a method signature and in generic type instantiation. Definuje třídu InvoiceItem s vlastností typu UInt32, vlastností typu Nullable(Of UInt32)a konstruktor s parametry typu UInt32 a Nullable(Of UInt32).It defines an InvoiceItem class with a property of type UInt32, a property of type Nullable(Of UInt32), and a constructor with parameters of type UInt32 and Nullable(Of UInt32). Při pokusu o zkompilování tohoto příkladu získáte čtyři upozornění kompilátoru.You get four compiler warnings when you try to compile this example.

using System;

[assembly: CLSCompliant(true)]

public class InvoiceItem
{
   private uint invId = 0;
   private uint itemId = 0;
   private Nullable<uint> qty;

   public InvoiceItem(uint sku, Nullable<uint> quantity)
   {
      itemId = sku;
      qty = quantity;
   }

   public Nullable<uint> Quantity
   {
      get { return qty; }
      set { qty = value; }
   }

   public uint InvoiceId
   {
      get { return invId; }
      set { invId = value; }
   }
}
// The attempt to compile the example displays the following output:
//    Type1.cs(13,23): warning CS3001: Argument type 'uint' is not CLS-compliant
//    Type1.cs(13,33): warning CS3001: Argument type 'uint?' is not CLS-compliant
//    Type1.cs(19,26): warning CS3003: Type of 'InvoiceItem.Quantity' is not CLS-compliant
//    Type1.cs(25,16): warning CS3003: Type of 'InvoiceItem.InvoiceId' is not CLS-compliant
<Assembly: CLSCompliant(True)>

Public Class InvoiceItem

   Private invId As UInteger = 0
   Private itemId As UInteger = 0
   Private qty AS Nullable(Of UInteger)
   
   Public Sub New(sku As UInteger, quantity As Nullable(Of UInteger))
      itemId = sku
      qty = quantity
   End Sub

   Public Property Quantity As Nullable(Of UInteger)
      Get
         Return qty
      End Get   
      Set 
         qty = value
      End Set   
   End Property

   Public Property InvoiceId As UInteger
      Get   
         Return invId
      End Get
      Set 
         invId = value
      End Set   
   End Property
End Class
' The attempt to compile the example displays output similar to the following:
'    Type1.vb(13) : warning BC40028: Type of parameter 'sku' is not CLS-compliant.
'    
'       Public Sub New(sku As UInteger, quantity As Nullable(Of UInteger))
'                      ~~~
'    Type1.vb(13) : warning BC40041: Type 'UInteger' is not CLS-compliant.
'    
'       Public Sub New(sku As UInteger, quantity As Nullable(Of UInteger))
'                                                               ~~~~~~~~
'    Type1.vb(18) : warning BC40041: Type 'UInteger' is not CLS-compliant.
'    
'       Public Property Quantity As Nullable(Of UInteger)
'                                               ~~~~~~~~
'    Type1.vb(27) : warning BC40027: Return type of function 'InvoiceId' is not CLS-compliant.
'    
'       Public Property InvoiceId As UInteger
'                       ~~~~~~~~~

Chcete-li odstranit upozornění kompilátoru, nahraďte typy neodpovídající specifikaci CLS ve InvoiceItem veřejném rozhraní s vyhovujícími typy:To eliminate the compiler warnings, replace the non-CLS-compliant types in the InvoiceItem public interface with compliant types:

using System;

[assembly: CLSCompliant(true)]

public class InvoiceItem
{
   private uint invId = 0;
   private uint itemId = 0;
   private Nullable<int> qty;

   public InvoiceItem(int sku, Nullable<int> quantity)
   {
      if (sku <= 0)
         throw new ArgumentOutOfRangeException("The item number is zero or negative.");
      itemId = (uint) sku;
      
      qty = quantity;
   }

   public Nullable<int> Quantity
   {
      get { return qty; }
      set { qty = value; }
   }

   public int InvoiceId
   {
      get { return (int) invId; }
      set { 
         if (value <= 0)
            throw new ArgumentOutOfRangeException("The invoice number is zero or negative.");
         invId = (uint) value; }
   }
}
<Assembly: CLSCompliant(True)>

Public Class InvoiceItem

   Private invId As UInteger = 0
   Private itemId As UInteger = 0
   Private qty AS Nullable(Of Integer)
   
   Public Sub New(sku As Integer, quantity As Nullable(Of Integer))
      If sku <= 0 Then
         Throw New ArgumentOutOfRangeException("The item number is zero or negative.")
      End If
      itemId = CUInt(sku)
      qty = quantity
   End Sub

   Public Property Quantity As Nullable(Of Integer)
      Get
         Return qty
      End Get   
      Set 
         qty = value
      End Set   
   End Property

   Public Property InvoiceId As Integer
      Get   
         Return CInt(invId)
      End Get
      Set 
         invId = CUInt(value)
      End Set   
   End Property
End Class

Kromě specifických typů uvedených v některé kategorie typů nejsou kompatibilní se specifikací CLS.In addition to the specific types listed, some categories of types are not CLS compliant. Mezi ně patří nespravované typy ukazatelů a typy ukazatelů na funkce.These include unmanaged pointer types and function pointer types. Následující příklad vygeneruje upozornění kompilátoru, protože používá ukazatel na celé číslo pro vytvoření pole celých čísel.The following example generates a compiler warning because it uses a pointer to an integer to create an array of integers.

using System;

[assembly: CLSCompliant(true)]

public class ArrayHelper
{
   unsafe public static Array CreateInstance(Type type, int* ptr, int items)
   {
      Array arr = Array.CreateInstance(type, items);
      int* addr = ptr;
      for (int ctr = 0; ctr < items; ctr++) {
          int value = *addr;
          arr.SetValue(value, ctr);
          addr++;
      }
      return arr;
   }
}   
// The attempt to compile this example displays the following output:
//    UnmanagedPtr1.cs(8,57): warning CS3001: Argument type 'int*' is not CLS-compliant

Pro abstraktní třídy kompatibilní se specifikací CLS (to znamená, třídy označené jako abstract C# v nebo jako MustInherit v Visual Basic) musí být všichni členové třídy také kompatibilní se specifikací CLS.For CLS-compliant abstract classes (that is, classes marked as abstract in C# or as MustInherit in Visual Basic), all members of the class must also be CLS-compliant.

Zásady vytváření názvůNaming conventions

Vzhledem k tomu, že některé programovací jazyky rozlišují velká a malá písmena, se musí identifikátory (například názvy oborů názvů, typů a členů) lišit o více než případu.Because some programming languages are case-insensitive, identifiers (such as the names of namespaces, types, and members) must differ by more than case. Dva identifikátory jsou považovány za ekvivalentní, pokud je jejich mapování malých písmen stejné.Two identifiers are considered equivalent if their lowercase mappings are the same. Následující C# příklad definuje dvě veřejné třídy Person a person.The following C# example defines two public classes, Person and person. Protože se liší pouze v případě, C# kompilátor je označí jako nekompatibilní se specifikací CLS.Because they differ only by case, the C# compiler flags them as not CLS-compliant.

using System;

[assembly: CLSCompliant(true)]

public class Person : person
{
 
}

public class person
{
 
}
// Compilation produces a compiler warning like the following:
//    Naming1.cs(11,14): warning CS3005: Identifier 'person' differing 
//                       only in case is not CLS-compliant
//    Naming1.cs(6,14): (Location of symbol related to previous warning)

Identifikátory programovacích jazyků, jako jsou názvy oborů názvů, typů a členů, musí být v souladu se standardem Unicode 3,0, technickým hlášením 15, přílohou 7.Programming language identifiers, such as the names of namespaces, types, and members, must conform to the Unicode Standard 3.0, Technical Report 15, Annex 7. To znamená, že:This means that:

  • Prvním znakem identifikátoru může být jakékoli velké písmeno Unicode, malé písmeno, název písmene, písmeno, písmeno, jiné písmeno nebo číslo písmen.The first character of an identifier can be any Unicode uppercase letter, lowercase letter, title case letter, modifier letter, other letter, or letter number. Informace o kategoriích znaků Unicode naleznete v System.Globalization.UnicodeCategory výčtu.For information on Unicode character categories, see the System.Globalization.UnicodeCategory enumeration.

  • Další znaky mohou být z libovolné kategorie jako první znak a mohou také obsahovat značky bez mezer mezi mezerami, kombinováním značek mezer, desetinnými čísly, interpunkční znaménky konektoru a formátovacími kódy.Subsequent characters can be from any of the categories as the first character, and can also include non-spacing marks, spacing combining marks, decimal numbers, connector punctuations, and formatting codes.

Před porovnáním identifikátorů byste měli odfiltrovat Formátovací kódy a převést identifikátory na normalizační formu Unicode C, protože jeden znak může být reprezentován více jednotkami kódu zakódovanými v kódování UTF-16.Before you compare identifiers, you should filter out formatting codes and convert the identifiers to Unicode Normalization Form C, because a single character can be represented by multiple UTF-16-encoded code units. Sekvence znaků, které vytvářejí stejné jednotky kódu ve formě normalizace Unicode C, nejsou kompatibilní se specifikací CLS.Character sequences that produce the same code units in Unicode Normalization Form C are not CLS-compliant. Následující příklad definuje vlastnost s názvem , která se skládá z znaku ANGSTROM SIGN (U + 212B), a druhé vlastnosti s názvem Å, která se skládá z znaku velké písmeno latinky A s výše UVEDENým PRSTENci (U + 00C5).The following example defines a property named , which consists of the character ANGSTROM SIGN (U+212B), and a second property named Å, which consists of the character LATIN CAPITAL LETTER A WITH RING ABOVE (U+00C5). Kompilátory C# i Visual Basic označí zdrojový kód jako nekompatibilní se specifikací CLS.Both the C# and Visual Basic compilers flag the source code as non-CLS-compliant.

public class Size
{
   private double a1;
   private double a2;
   
   public double Å
   {
       get { return a1; }
       set { a1 = value; }
   }         
         
   public double Å
   {
       get { return a2; }
       set { a2 = value; }
   }
}
// Compilation produces a compiler warning like the following:
//    Naming2a.cs(16,18): warning CS3005: Identifier 'Size.Å' differing only in case is not
//            CLS-compliant
//    Naming2a.cs(10,18): (Location of symbol related to previous warning)
//    Naming2a.cs(18,8): warning CS3005: Identifier 'Size.Å.get' differing only in case is not
//            CLS-compliant
//    Naming2a.cs(12,8): (Location of symbol related to previous warning)
//    Naming2a.cs(19,8): warning CS3005: Identifier 'Size.Å.set' differing only in case is not
//            CLS-compliant
//    Naming2a.cs(13,8): (Location of symbol related to previous warning)
<Assembly: CLSCompliant(True)>
Public Class Size
   Private a1 As Double
   Private a2 As Double
   
   Public Property Å As Double
       Get
          Return a1
       End Get
       Set 
          a1 = value
       End Set
   End Property         
         
   Public Property Å As Double
       Get
          Return a2
       End Get
       Set
          a2 = value
       End Set   
   End Property
End Class
' Compilation produces a compiler warning like the following:
'    Naming1.vb(9) : error BC30269: 'Public Property Å As Double' has multiple definitions
'     with identical signatures.
'    
'       Public Property Å As Double
'                       ~

Názvy členů v rámci určitého oboru (například obory názvů v rámci sestavení, typy v rámci oboru názvů nebo členy v rámci typu) musí být jedinečné s výjimkou názvů, které jsou přeloženy prostřednictvím přetížení.Member names within a particular scope (such as the namespaces within an assembly, the types within a namespace, or the members within a type) must be unique except for names that are resolved through overloading. Tento požadavek je přísnější než u společného systému typů, což umožňuje více členům v rámci oboru mít stejné názvy, pokud jsou různé druhy členů (například jedna je metoda a jedna je pole).This requirement is more stringent than that of the common type system, which allows multiple members within a scope to have identical names as long as they are different kinds of members (for example, one is a method and one is a field). Konkrétně pro členy typu:In particular, for type members:

  • Pole a vnořené typy jsou rozlišeny pouze podle názvu.Fields and nested types are distinguished by name alone.

  • Metody, vlastnosti a události, které mají stejný název, se musí lišit více než pouhým návratovým typem.Methods, properties, and events that have the same name must differ by more than just return type.

Následující příklad znázorňuje požadavek, aby názvy členů musely být v rámci svého oboru jedinečné.The following example illustrates the requirement that member names must be unique within their scope. Definuje třídu s názvem Converter, která obsahuje čtyři členy s názvem Conversion.It defines a class named Converter that includes four members named Conversion. Tři jsou metody a jedna je vlastnost.Three are methods, and one is a property. Metoda, která obsahuje parametr Int64, je jednoznačně pojmenována, ale tyto dvě metody s parametrem Int32 nejsou, protože návratová hodnota není považována za součást signatury člena.The method that includes an Int64 parameter is uniquely named, but the two methods with an Int32 parameter are not, because return value is not considered a part of a member's signature. Vlastnost Conversion také porušuje tento požadavek, protože vlastnosti nemohou mít stejný název jako přetížené metody.The Conversion property also violates this requirement, because properties cannot have the same name as overloaded methods.

using System;

[assembly: CLSCompliant(true)]

public class Converter
{
   public double Conversion(int number)
   {
      return (double) number;
   }

   public float Conversion(int number)
   {
      return (float) number;
   }
   
   public double Conversion(long number)
   {
      return (double) number;
   }
   
   public bool Conversion
   {
      get { return true; }
   }     
}  
// Compilation produces a compiler error like the following:
//    Naming3.cs(13,17): error CS0111: Type 'Converter' already defines a member called
//            'Conversion' with the same parameter types
//    Naming3.cs(8,18): (Location of symbol related to previous error)
//    Naming3.cs(23,16): error CS0102: The type 'Converter' already contains a definition for
//            'Conversion'
//    Naming3.cs(8,18): (Location of symbol related to previous error)
<Assembly: CLSCompliant(True)>

Public Class Converter
   Public Function Conversion(number As Integer) As Double
      Return CDbl(number)
   End Function

   Public Function Conversion(number As Integer) As Single
      Return CSng(number)
   End Function
   
   Public Function Conversion(number As Long) As Double
      Return CDbl(number)
   End Function
   
   Public ReadOnly Property Conversion As Boolean
      Get
         Return True
      End Get   
   End Property     
End Class
' Compilation produces a compiler error like the following:
'    Naming3.vb(8) : error BC30301: 'Public Function Conversion(number As Integer) As Double' 
'                    and 'Public Function Conversion(number As Integer) As Single' cannot 
'                    overload each other because they differ only by return types.
'    
'       Public Function Conversion(number As Integer) As Double
'                       ~~~~~~~~~~
'    Naming3.vb(20) : error BC30260: 'Conversion' is already declared as 'Public Function 
'                     Conversion(number As Integer) As Single' in this class.
'    
'       Public ReadOnly Property Conversion As Boolean
'                                ~~~~~~~~~~

Jednotlivé jazyky obsahují jedinečná klíčová slova, takže jazyky, které cílí na modul CLR (Common Language Runtime), musí také poskytovat určitý mechanismus pro odkazování na identifikátory (například názvy typů), které se shodují s klíčovými slovy.Individual languages include unique keywords, so languages that target the common language runtime must also provide some mechanism for referencing identifiers (such as type names) that coincide with keywords. Například case je klíčové slovo v obou C# i Visual Basic.For example, case is a keyword in both C# and Visual Basic. Následující příklad Visual Basic například umožňuje určit třídu s názvem case z klíčového slova case pomocí počátečních a uzavíracích složených závorek.However, the following Visual Basic example is able to disambiguate a class named case from the case keyword by using opening and closing braces. V opačném případě by tento příklad vytvořil chybovou zprávu "klíčové slovo není platné jako identifikátor" a kompilace se nezdařila.Otherwise, the example would produce the error message, "Keyword is not valid as an identifier," and fail to compile.

Public Class [case]
   Private _id As Guid
   Private name As String  
   
   Public Sub New(name As String)
      _id = Guid.NewGuid()
      Me.name = name 
   End Sub   
        
   Public ReadOnly Property ClientName As String
      Get
         Return name
      End Get
   End Property
End Class

V následujícím C# příkladu je možné vytvořit instanci case třídy pomocí symbolu @ pro odstranění identifikátoru z klíčového slova jazyka.The following C# example is able to instantiate the case class by using the @ symbol to disambiguate the identifier from the language keyword. Bez něj C# kompilátor zobrazí dvě chybové zprávy, "očekával se typ" a "neplatný výraz" Case ".Without it, the C# compiler would display two error messages, "Type expected" and "Invalid expression term 'case'."

using System;

public class Example
{
   public static void Main()
   {
      @case c = new @case("John");
      Console.WriteLine(c.ClientName);
   }
}

Převod typuType conversion

Specifikace CLS (Common Language Specification) definuje dva operátory převodu:The Common Language Specification defines two conversion operators:

  • op_Implicit, která se používá pro rozšiřující převody, které nemají za následek ztrátu dat nebo přesnost.op_Implicit, which is used for widening conversions that do not result in loss of data or precision. Například struktura Decimal obsahuje přetížený op_Implicit operátor pro převod hodnot integrálních typů a Char hodnot na hodnoty Decimal.For example, the Decimal structure includes an overloaded op_Implicit operator to convert values of integral types and Char values to Decimal values.

  • op_Explicit, která se používá pro zúžené převody, které mohou vést ke ztrátě velikosti (hodnota je převedena na hodnotu, která má menší rozsah) nebo přesnost.op_Explicit, which is used for narrowing conversions that can result in loss of magnitude (a value is converted to a value that has a smaller range) or precision. Například struktura Decimal obsahuje přetížený op_Explicit operátor k převedení Double a Single hodnot na Decimal a k převodu Decimal hodnot na integrální hodnoty, Double, Singlea Char.For example, the Decimal structure includes an overloaded op_Explicit operator to convert Double and Single values to Decimal and to convert Decimal values to integral values, Double, Single, and Char.

Ne všechny jazyky ale podporují přetížení operátoru nebo definici vlastních operátorů.However, not all languages support operator overloading or the definition of custom operators. Pokud se rozhodnete implementovat tyto operátory převodu, měli byste také poskytnout alternativní způsob, jak provést převod.If you choose to implement these conversion operators, you should also provide an alternate way to perform the conversion. Doporučujeme zadat Fromxxx a Toxxx metody.We recommend that you provide FromXxx and ToXxx methods.

Následující příklad definuje implicitní a explicitní převody kompatibilní se specifikací CLS.The following example defines CLS-compliant implicit and explicit conversions. Vytvoří třídu UDouble, která představuje podepsané číslo s dvojitou přesností a plovoucí desetinnou čárkou.It creates a UDouble class that represents an signed double-precision, floating-point number. Poskytuje implicitní převody z UDouble na Double a explicitní převod z UDouble na Single, Double na UDoublea Single na UDouble.It provides for implicit conversions from UDouble to Double and for explicit conversions from UDouble to Single, Double to UDouble, and Single to UDouble. Také definuje metodu ToDouble jako alternativu implicitního operátoru převodu a metody ToSingle, FromDoublea FromSingle jako alternativy pro explicitní operátory převodu.It also defines a ToDouble method as an alternative to the implicit conversion operator and the ToSingle, FromDouble, and FromSingle methods as alternatives to the explicit conversion operators.

using System;

public struct UDouble
{
   private double number;
   
   public UDouble(double value)
   {
      if (value < 0)
         throw new InvalidCastException("A negative value cannot be converted to a UDouble.");

      number = value;
   }
   
   public UDouble(float value)
   {
      if (value < 0)
         throw new InvalidCastException("A negative value cannot be converted to a UDouble.");

      number = value;
   }
   
   public static readonly UDouble MinValue = (UDouble) 0.0;
   public static readonly UDouble MaxValue = (UDouble) Double.MaxValue;
   
   public static explicit operator Double(UDouble value)
   {
      return value.number;
   }
   
   public static implicit operator Single(UDouble value)
   {
      if (value.number > (double) Single.MaxValue) 
         throw new InvalidCastException("A UDouble value is out of range of the Single type.");

      return (float) value.number;         
   }
   
   public static explicit operator UDouble(double value)
   {
      if (value < 0)
         throw new InvalidCastException("A negative value cannot be converted to a UDouble.");

      return new UDouble(value);
   } 

   public static implicit operator UDouble(float value)
   {
      if (value < 0)
         throw new InvalidCastException("A negative value cannot be converted to a UDouble.");

      return new UDouble(value);
   } 

   public static Double ToDouble(UDouble value)
   {
      return (Double) value;
   }   

   public static float ToSingle(UDouble value)
   {
      return (float) value;
   }   

   public static UDouble FromDouble(double value)
   {
      return new UDouble(value);
   }
   
   public static UDouble FromSingle(float value)
   {
      return new UDouble(value);
   }   
}
Public Structure UDouble
   Private number As Double
   
   Public Sub New(value As Double)
      If value < 0 Then
         Throw New InvalidCastException("A negative value cannot be converted to a UDouble.")
      End If
      number = value
   End Sub
   
   Public Sub New(value As Single)
      If value < 0 Then
         Throw New InvalidCastException("A negative value cannot be converted to a UDouble.")
      End If
      number = value
   End Sub
   
   Public Shared ReadOnly MinValue As UDouble = CType(0.0, UDouble)
   Public Shared ReadOnly MaxValue As UDouble = Double.MaxValue
   
   Public Shared Widening Operator CType(value As UDouble) As Double
      Return value.number
   End Operator
   
   Public Shared Narrowing Operator CType(value As UDouble) As Single
      If value.number > CDbl(Single.MaxValue) Then
         Throw New InvalidCastException("A UDouble value is out of range of the Single type.")
      End If
      Return CSng(value.number)         
   End Operator
   
   Public Shared Narrowing Operator CType(value As Double) As UDouble
      If value < 0 Then
         Throw New InvalidCastException("A negative value cannot be converted to a UDouble.")
      End If
      Return New UDouble(value)
   End Operator 

   Public Shared Narrowing Operator CType(value As Single) As UDouble
      If value < 0 Then
         Throw New InvalidCastException("A negative value cannot be converted to a UDouble.")
      End If
      Return New UDouble(value)
   End Operator 

   Public Shared Function ToDouble(value As UDouble) As Double
      Return CType(value, Double)
   End Function   

   Public Shared Function ToSingle(value As UDouble) As Single
      Return CType(value, Single)
   End Function   

   Public Shared Function FromDouble(value As Double) As UDouble
      Return New UDouble(value)
   End Function
   
   Public Shared Function FromSingle(value As Single) As UDouble
      Return New UDouble(value)
   End Function   
End Structure

PoleArrays

Pole kompatibilní se specifikací CLS odpovídají následujícím pravidlům:CLS-compliant arrays conform to the following rules:

  • Všechny dimenze pole musí mít dolní mez nula.All dimensions of an array must have a lower bound of zero. Následující příklad vytvoří pole, které není kompatibilní se specifikací CLS, s dolní mezí jedna.The following example creates a non-CLS-compliant array with a lower bound of one. Všimněte si, že navzdory přítomnosti atributu CLSCompliantAttribute kompilátor nezjistí, že pole vrácené metodou Numbers.GetTenPrimes není kompatibilní se specifikací CLS.Note that, despite the presence of the CLSCompliantAttribute attribute, the compiler does not detect that the array returned by the Numbers.GetTenPrimes method is not CLS-compliant.

    [assembly: CLSCompliant(true)]
    
    public class Numbers
    {
       public static Array GetTenPrimes()
       {
          Array arr = Array.CreateInstance(typeof(Int32), new int[] {10}, new int[] {1});
          arr.SetValue(1, 1);
          arr.SetValue(2, 2);
          arr.SetValue(3, 3);
          arr.SetValue(5, 4);
          arr.SetValue(7, 5);
          arr.SetValue(11, 6);
          arr.SetValue(13, 7);
          arr.SetValue(17, 8);
          arr.SetValue(19, 9);
          arr.SetValue(23, 10);
    
          return arr; 
       }
    }
    
    <Assembly: CLSCompliant(True)>
    
    Public Class Numbers
       Public Shared Function GetTenPrimes() As Array
          Dim arr As Array = Array.CreateInstance(GetType(Int32), {10}, {1})
          arr.SetValue(1, 1)
          arr.SetValue(2, 2)
          arr.SetValue(3, 3)
          arr.SetValue(5, 4)
          arr.SetValue(7, 5)
          arr.SetValue(11, 6)
          arr.SetValue(13, 7)
          arr.SetValue(17, 8)
          arr.SetValue(19, 9)
          arr.SetValue(23, 10)
          
          Return arr
       End Function
    End Class
    
  • Všechny prvky pole musí obsahovat typy kompatibilní se specifikací CLS.All array elements must consist of CLS-compliant types. Následující příklad definuje dvě metody, které vracejí pole neodpovídající specifikaci CLS.The following example defines two methods that return non-CLS-compliant arrays. První vrátí pole hodnot UInt32.The first returns an array of UInt32 values. Druhá vrátí Object pole, které obsahuje hodnoty Int32 a UInt32.The second returns an Object array that includes Int32 and UInt32 values. I když kompilátor identifikuje první pole jako nevyhovující z důvodu jeho UInt32ho typu, nerozpozná, že druhé pole obsahuje prvky, které nejsou kompatibilní se specifikací CLS.Although the compiler identifies the first array as non-compliant because of its UInt32 type, it fails to recognize that the second array includes non-CLS-compliant elements.

    using System;
    
    [assembly: CLSCompliant(true)]
    
    public class Numbers
    {
       public static UInt32[] GetTenPrimes()
       {
          uint[] arr = { 1u, 2u, 3u, 5u, 7u, 11u, 13u, 17u, 19u };
          return arr;
       }
       
       public static Object[] GetFivePrimes()
       {
          Object[] arr = { 1, 2, 3, 5u, 7u };
          return arr;
       }
    }
    // Compilation produces a compiler warning like the following:
    //    Array2.cs(8,27): warning CS3002: Return type of 'Numbers.GetTenPrimes()' is not
    //            CLS-compliant
    
    <Assembly: CLSCompliant(True)>
    
    Public Class Numbers
       Public Shared Function GetTenPrimes() As UInt32()
          Return { 1ui, 2ui, 3ui, 5ui, 7ui, 11ui, 13ui, 17ui, 19ui }
       End Function
       
       Public Shared Function GetFivePrimes() As Object()
          Dim arr() As Object = { 1, 2, 3, 5ui, 7ui }
          Return arr
       End Function
    End Class
    ' Compilation produces a compiler warning like the following:
    '    warning BC40027: Return type of function 'GetTenPrimes' is not CLS-compliant.
    '    
    '       Public Shared Function GetTenPrimes() As UInt32()
    '                              ~~~~~~~~~~~~
    
  • Rozlišení přetěžování pro metody, které mají parametry pole, je založené na tom, že se jedná o pole a na jejich typu prvku.Overload resolution for methods that have array parameters is based on the fact that they are arrays and on their element type. Z tohoto důvodu je následující definice přetížené metody GetSquares kompatibilní se specifikací CLS.For this reason, the following definition of an overloaded GetSquares method is CLS-compliant.

    using System;
    using System.Numerics;
    
    [assembly: CLSCompliant(true)]
    
    public class Numbers
    {
       public static byte[] GetSquares(byte[] numbers)
       {
          byte[] numbersOut = new byte[numbers.Length];
          for (int ctr = 0; ctr < numbers.Length; ctr++) {
             int square = ((int) numbers[ctr]) * ((int) numbers[ctr]); 
             if (square <= Byte.MaxValue)
                numbersOut[ctr] = (byte) square;
             // If there's an overflow, assign MaxValue to the corresponding 
             // element.
             else
                numbersOut[ctr] = Byte.MaxValue;
    
          }
          return numbersOut;
       }
    
       public static BigInteger[] GetSquares(BigInteger[] numbers)
       {
          BigInteger[] numbersOut = new BigInteger[numbers.Length];
          for (int ctr = 0; ctr < numbers.Length; ctr++)
             numbersOut[ctr] = numbers[ctr] * numbers[ctr]; 
    
          return numbersOut;
       }
    }
    
    Imports System.Numerics
    
    <Assembly: CLSCompliant(True)>
    
    Public Module Numbers
       Public Function GetSquares(numbers As Byte()) As Byte()
          Dim numbersOut(numbers.Length - 1) As Byte
          For ctr As Integer = 0 To numbers.Length - 1
             Dim square As Integer = (CInt(numbers(ctr)) * CInt(numbers(ctr))) 
             If square <= Byte.MaxValue Then
                numbersOut(ctr) = CByte(square)
             ' If there's an overflow, assign MaxValue to the corresponding 
             ' element.
             Else
                numbersOut(ctr) = Byte.MaxValue
             End If   
          Next
          Return numbersOut
       End Function
    
       Public Function GetSquares(numbers As BigInteger()) As BigInteger()
          Dim numbersOut(numbers.Length - 1) As BigInteger
          For ctr As Integer = 0 To numbers.Length - 1
             numbersOut(ctr) = numbers(ctr) * numbers(ctr) 
          Next
          Return numbersOut
       End Function
    End Module
    

RozhraníInterfaces

Rozhraní kompatibilní se specifikací CLS mohou definovat vlastnosti, události a virtuální metody (metody bez implementace).CLS-compliant interfaces can define properties, events, and virtual methods (methods with no implementation). Rozhraní kompatibilní se specifikací CLS nemůže mít následující:A CLS-compliant interface cannot have any of the following:

  • Statické metody nebo statická pole.Static methods or static fields. Kompilátory C# i Visual Basic generují chyby kompilátoru, pokud definujete statického člena v rozhraní.Both the C# and Visual Basic compilers generate compiler errors if you define a static member in an interface.

  • Pole.Fields. Kompilátory C# i Visual Basic generují chyby kompilátoru, pokud definujete pole v rozhraní.Both the C# and Visual Basic compilers generate compiler errors if you define a field in an interface.

  • Metody, které nejsou kompatibilní se specifikací CLS.Methods that are not CLS-compliant. Například následující definice rozhraní zahrnuje metodu, INumber.GetUnsigned, která je označena jako nekompatibilní se specifikací CLS.For example, the following interface definition includes a method, INumber.GetUnsigned, that is marked as non-CLS-compliant. Tento příklad generuje upozornění kompilátoru.This example generates a compiler warning.

    using System;
    
    [assembly:CLSCompliant(true)]
    
    public interface INumber
    {
       int Length();
       [CLSCompliant(false)] ulong GetUnsigned();
    }
    // Attempting to compile the example displays output like the following:
    //    Interface2.cs(8,32): warning CS3010: 'INumber.GetUnsigned()': CLS-compliant interfaces
    //            must have only CLS-compliant members
    
    <Assembly: CLSCompliant(True)>
    
    Public Interface INumber
       Function Length As Integer
       
       <CLSCompliant(False)> Function GetUnsigned As ULong   
    End Interface
    ' Attempting to compile the example displays output like the following:
    '    Interface2.vb(9) : warning BC40033: Non CLS-compliant 'function' is not allowed in a 
    '    CLS-compliant interface.
    '    
    '       <CLSCompliant(False)> Function GetUnsigned As ULong
    '                                      ~~~~~~~~~~~
    

    Vzhledem k tomuto pravidlu nejsou typy kompatibilní se specifikací CLS vyžadovány k implementaci členů, které nedodržují specifikaci CLS.Because of this rule, CLS-compliant types are not required to implement non-CLS-compliant members. Pokud rozhraní kompatibilní se specifikací CLS zveřejňuje třídu, která implementuje rozhraní nekompatibilní se specifikací CLS, měla by také poskytnout konkrétní implementace všech členů nekompatibilních se specifikací CLS.If a CLS-compliant framework does expose a class that implements a non-CLS compliant interface, it should also provide concrete implementations of all non-CLS-compliant members.

Kompilátory jazyka odpovídající specifikaci CLS musí také umožňovat třídě, aby poskytovala samostatné implementace členů, kteří mají stejný název a signaturu ve více rozhraních.CLS-compliant language compilers must also allow a class to provide separate implementations of members that have the same name and signature in multiple interfaces. C# A Visual Basic podporují explicitní implementace rozhraní , které poskytují různé implementace identicky pojmenovaných metod.Both C# and Visual Basic support explicit interface implementations to provide different implementations of identically named methods. Visual Basic také podporuje klíčové slovo Implements, které umožňuje explicitně určit, které rozhraní a člen určitý člen implementuje.Visual Basic also supports the Implements keyword, which enables you to explicitly designate which interface and member a particular member implements. Následující příklad znázorňuje tento scénář definováním Temperature třídy, která implementuje rozhraní ICelsius a IFahrenheit jako explicitní implementace rozhraní.The following example illustrates this scenario by defining a Temperature class that implements the ICelsius and IFahrenheit interfaces as explicit interface implementations.

using System;

[assembly: CLSCompliant(true)]

public interface IFahrenheit
{
   decimal GetTemperature();
}

public interface ICelsius
{
   decimal GetTemperature();
}

public class Temperature : ICelsius, IFahrenheit
{
   private decimal _value;
   
   public Temperature(decimal value)
   {
      // We assume that this is the Celsius value.
      _value = value;
   } 
   
   decimal IFahrenheit.GetTemperature()
   {
      return _value * 9 / 5 + 32;
   }

   decimal ICelsius.GetTemperature()
   {
      return _value;
   } 
}
public class Example
{
   public static void Main()
   {
      Temperature temp = new Temperature(100.0m);
      ICelsius cTemp = temp;
      IFahrenheit fTemp = temp;
      Console.WriteLine("Temperature in Celsius: {0} degrees", 
                        cTemp.GetTemperature());
      Console.WriteLine("Temperature in Fahrenheit: {0} degrees", 
                        fTemp.GetTemperature());
   }
}
// The example displays the following output:
//       Temperature in Celsius: 100.0 degrees
//       Temperature in Fahrenheit: 212.0 degrees
<Assembly: CLSCompliant(True)>

Public Interface IFahrenheit
   Function GetTemperature() As Decimal
End Interface
   
Public Interface ICelsius
   Function GetTemperature() As Decimal
End Interface

Public Class Temperature : Implements ICelsius, IFahrenheit
   Private _value As Decimal
   
   Public Sub New(value As Decimal)
      ' We assume that this is the Celsius value.
      _value = value
   End Sub 
   
   Public Function GetFahrenheit() As Decimal _
          Implements IFahrenheit.GetTemperature
      Return _value * 9 / 5 + 32
   End Function

   Public Function GetCelsius() As Decimal _
          Implements ICelsius.GetTemperature
      Return _value
   End Function 
End Class

Module Example
   Public Sub Main()
      Dim temp As New Temperature(100.0d)
      Console.WriteLine("Temperature in Celsius: {0} degrees", 
                        temp.GetCelsius())
      Console.WriteLine("Temperature in Fahrenheit: {0} degrees", 
                        temp.GetFahrenheit())
   End Sub
End Module
' The example displays the following output:
'       Temperature in Celsius: 100.0 degrees
'       Temperature in Fahrenheit: 212.0 degrees

VýčtyEnumerations

Výčty kompatibilní se specifikací CLS musí dodržovat tato pravidla:CLS-compliant enumerations must follow these rules:

  • Podkladový typ výčtu musí být vnitřní celé číslo kompatibilní se specifikací CLS (Byte, Int16, Int32nebo Int64).The underlying type of the enumeration must be an intrinsic CLS-compliant integer (Byte, Int16, Int32, or Int64). Například následující kód se pokusí definovat výčet, jehož základní typ je UInt32 a vygeneruje upozornění kompilátoru.For example, the following code tries to define an enumeration whose underlying type is UInt32 and generates a compiler warning.

    using System;
    
    [assembly: CLSCompliant(true)]
    
    public enum Size : uint { 
       Unspecified = 0, 
       XSmall = 1, 
       Small = 2, 
       Medium = 3, 
       Large = 4, 
       XLarge = 5 
    };
    
    public class Clothing
    {
       public string Name; 
       public string Type;
       public string Size;
    }
    // The attempt to compile the example displays a compiler warning like the following:
    //    Enum3.cs(6,13): warning CS3009: 'Size': base type 'uint' is not CLS-compliant
    
    <Assembly: CLSCompliant(True)>
    
    Public Enum Size As UInt32
       Unspecified = 0
       XSmall = 1
       Small = 2
       Medium = 3
       Large = 4
       XLarge = 5
    End Enum
    
    Public Class Clothing
       Public Name As String
       Public Type As String
       Public Size As Size
    End Class
    ' The attempt to compile the example displays a compiler warning like the following:
    '    Enum3.vb(6) : warning BC40032: Underlying type 'UInt32' of Enum is not CLS-compliant.
    '    
    '    Public Enum Size As UInt32
    '                ~~~~
    
  • Typ výčtu musí mít jedno pole instance s názvem Value__, které je označeno atributem FieldAttributes.RTSpecialName.An enumeration type must have a single instance field named Value__ that is marked with the FieldAttributes.RTSpecialName attribute. To umožňuje implicitně odkazovat na hodnotu pole.This enables you to reference the field value implicitly.

  • Výčet zahrnuje statická pole literálů, jejichž typy se shodují s typem výčtu samotného.An enumeration includes literal static fields whose types match the type of the enumeration itself. Například pokud definujete State výčtu s hodnotami State.On a State.Off, State.On a State.Off jsou obě literální statická pole, jejichž typ je State.For example, if you define a State enumeration with values of State.On and State.Off, State.On and State.Off are both literal static fields whose type is State.

  • Existují dva druhy výčtů:There are two kinds of enumerations:

    • Výčet, který představuje sadu vzájemně se vylučujících pojmenovaných celočíselných hodnot.An enumeration that represents a set of mutually exclusive, named integer values. Tento typ výčtu je označen nepřítomností vlastního atributu System.FlagsAttribute.This type of enumeration is indicated by the absence of the System.FlagsAttribute custom attribute.

    • Výčet, který představuje sadu bitových příznaků, které lze kombinovat k vygenerování nepojmenované hodnoty.An enumeration that represents a set of bit flags that can combine to generate an unnamed value. Tento typ výčtu je označen přítomností vlastního atributu System.FlagsAttribute.This type of enumeration is indicated by the presence of the System.FlagsAttribute custom attribute.

    Další informace najdete v dokumentaci ke struktuře Enum.For more information, see the documentation for the Enum structure.

  • Hodnota výčtu není omezena na rozsah zadaných hodnot.The value of an enumeration is not limited to the range of its specified values. Jinými slovy rozsah hodnot ve výčtu je rozsah své základní hodnoty.In other words, the range of values in an enumeration is the range of its underlying value. K určení, zda je zadaná hodnota členem výčtu, lze použít metodu Enum.IsDefined.You can use the Enum.IsDefined method to determine whether a specified value is a member of an enumeration.

Obecné typy členůType members in general

Specifikace CLS (Common Language Specification) vyžaduje, aby všechna pole a metody byly dostupné jako členové konkrétní třídy.The Common Language Specification requires all fields and methods to be accessed as members of a particular class. Proto globální statická pole a metody (tj. statická pole nebo metody, které jsou definovány odděleně od typu) nejsou kompatibilní se specifikací CLS.Therefore, global static fields and methods (that is, static fields or methods that are defined apart from a type) are not CLS-compliant. Pokud se pokusíte zahrnout globální pole nebo metodu do zdrojového kódu, kompilátory C# a Visual Basic generují chybu kompilátoru.If you try to include a global field or method in your source code, both the C# and Visual Basic compilers generate a compiler error.

Specifikace CLS (Common Language Specification) podporuje pouze standardní spravovanou konvenci volání.The Common Language Specification supports only the standard managed calling convention. Nepodporuje konvence nespravovaného volání a metody se seznamy argumentů proměnných označenými klíčovým slovem varargs.It doesn't support unmanaged calling conventions and methods with variable argument lists marked with the varargs keyword. U seznamů argumentů proměnných, které jsou kompatibilní se standardní spravovanou konvencí volání, použijte atribut ParamArrayAttribute nebo implementaci jednotlivého jazyka, například klíčové slovo params v C# a klíčová slova ParamArray v Visual Basic.For variable argument lists that are compatible with the standard managed calling convention, use the ParamArrayAttribute attribute or the individual language's implementation, such as the params keyword in C# and the ParamArray keyword in Visual Basic.

Přístupnost členaMember accessibility

Přepsání zděděného člena nemůže změnit přístupnost daného člena.Overriding an inherited member cannot change the accessibility of that member. Například veřejná metoda v základní třídě nemůže být přepsána soukromou metodou v odvozené třídě.For example, a public method in a base class cannot be overridden by a private method in a derived class. Existuje jedna výjimka: člen protected internal (in C#) nebo Protected Friend (v Visual Basic) v jednom sestavení, který je přepsán typem v jiném sestavení.There is one exception: a protected internal (in C#) or Protected Friend (in Visual Basic) member in one assembly that is overridden by a type in a different assembly. V takovém případě je přístup k přepsání Protected.In that case, the accessibility of the override is Protected.

Následující příklad ilustruje chybu, která je generována, když je atribut CLSCompliantAttribute nastaven na hodnotu truea Human, což je třída odvozená od Animal, se pokusí změnit přístupnost vlastnosti Species z veřejného na Private.The following example illustrates the error that is generated when the CLSCompliantAttribute attribute is set to true, and Human, which is a class derived from Animal, tries to change the accessibility of the Species property from public to private. Příklad se úspěšně zkompiluje, pokud je jeho přístupnost změněno na veřejné.The example compiles successfully if its accessibility is changed to public.

using System;

[assembly: CLSCompliant(true)]

public class Animal
{
   private string _species;
   
   public Animal(string species)
   {
      _species = species;
   }
   
   public virtual string Species 
   {    
      get { return _species; }
   }
   
   public override string ToString()
   {
      return _species;   
   } 
}

public class Human : Animal
{
   private string _name;
   
   public Human(string name) : base("Homo Sapiens")
   {
      _name = name;
   }
   
   public string Name
   {
      get { return _name; }
   }
   
   private override string Species 
   {
      get { return base.Species; }
   }
   
   public override string ToString() 
   {
      return _name;
   }
}

public class Example
{
   public static void Main()
   {
      Human p = new Human("John");
      Console.WriteLine(p.Species);
      Console.WriteLine(p.ToString());
   }
}
// The example displays the following output:
//    error CS0621: 'Human.Species': virtual or abstract members cannot be private
<Assembly: CLSCompliant(True)>

Public Class Animal
   Private _species As String
   
   Public Sub New(species As String)
      _species = species
   End Sub
   
   Public Overridable ReadOnly Property Species As String
      Get
         Return _species
      End Get
   End Property
   
   Public Overrides Function ToString() As String
      Return _species   
   End Function 
End Class

Public Class Human : Inherits Animal
   Private _name As String
   
   Public Sub New(name As String)
      MyBase.New("Homo Sapiens")
      _name = name
   End Sub
   
   Public ReadOnly Property Name As String
      Get
         Return _name
      End Get
   End Property
   
   Private Overrides ReadOnly Property Species As String
      Get
         Return MyBase.Species
      End Get   
   End Property
   
   Public Overrides Function ToString() As String
      Return _name
   End Function
End Class

Public Module Example
   Public Sub Main()
      Dim p As New Human("John")
      Console.WriteLine(p.Species)
      Console.WriteLine(p.ToString())
   End Sub
End Module
' The example displays the following output:
'     'Private Overrides ReadOnly Property Species As String' cannot override 
'     'Public Overridable ReadOnly Property Species As String' because
'      they have different access levels.
' 
'         Private Overrides ReadOnly Property Species As String

Typy v signatuře člena musí být přístupné, kdykoli je tento člen přístupný.Types in the signature of a member must be accessible whenever that member is accessible. Například to znamená, že veřejný člen nemůže obsahovat parametr, jehož typ je Private, Protected nebo Internal.For example, this means that a public member cannot include a parameter whose type is private, protected, or internal. Následující příklad ukazuje chybu kompilátoru, která je výsledkem, když konstruktor třídy StringWrapper zpřístupňuje interní hodnotu výčtu StringOperationType, která určuje, jak má být hodnota řetězce zabalena.The following example illustrates the compiler error that results when a StringWrapper class constructor exposes an internal StringOperationType enumeration value that determines how a string value should be wrapped.

using System;
using System.Text;

public class StringWrapper
{
   string internalString;
   StringBuilder internalSB = null;
   bool useSB = false;
   
   public StringWrapper(StringOperationType type)
   {   
      if (type == StringOperationType.Normal) {
         useSB = false;
      }   
      else {
         useSB = true;
         internalSB = new StringBuilder();
      }    
   }
   
   // The remaining source code...
}

internal enum StringOperationType { Normal, Dynamic }
// The attempt to compile the example displays the following output:
//    error CS0051: Inconsistent accessibility: parameter type
//            'StringOperationType' is less accessible than method
//            'StringWrapper.StringWrapper(StringOperationType)'
Imports System.Text

<Assembly:CLSCompliant(True)>

Public Class StringWrapper
   
   Dim internalString As String
   Dim internalSB As StringBuilder = Nothing
   Dim useSB As Boolean = False
   
   Public Sub New(type As StringOperationType)   
      If type = StringOperationType.Normal Then
         useSB = False
      Else
         internalSB = New StringBuilder() 
         useSB = True
      End If    
   End Sub
   
   ' The remaining source code...
End Class

Friend Enum StringOperationType As Integer
   Normal = 0
   Dynamic = 1
End Enum
' The attempt to compile the example displays the following output:
'    error BC30909: 'type' cannot expose type 'StringOperationType'
'     outside the project through class 'StringWrapper'.
'    
'       Public Sub New(type As StringOperationType)
'                              ~~~~~~~~~~~~~~~~~~~

Obecné typy a členyGeneric types and members

Vnořené typy mají vždy alespoň tolik obecných parametrů jako jejich nadřazený typ.Nested types always have at least as many generic parameters as their enclosing type. Odpovídají umístění obecným parametrům v nadřazeném typu.These correspond by position to the generic parameters in the enclosing type. Obecný typ může obsahovat také nové obecné parametry.The generic type can also include new generic parameters.

Vztah mezi parametry obecného typu obsahujícího typu a jeho vnořenými typy mohou být skryty syntaxí jednotlivých jazyků.The relationship between the generic type parameters of a containing type and its nested types may be hidden by the syntax of individual languages. V následujícím příkladu je obecný typ Outer<T> obsahuje dvě vnořené třídy, Inner1A a Inner1B<U>.In the following example, a generic type Outer<T> contains two nested classes, Inner1A and Inner1B<U>. Volání metody ToString, kterou jednotlivé třídy dědí z Object.ToString, ukazují, že každá vnořená třída obsahuje parametry typu své nadřazené třídy.The calls to the ToString method, which each class inherits from Object.ToString, show that each nested class includes the type parameters of its containing class.

using System;

[assembly:CLSCompliant(true)]

public class Outer<T>
{
   T value;
   
   public Outer(T value)
   {
      this.value = value;
   }
   
   public class Inner1A : Outer<T>
   {
      public Inner1A(T value) : base(value)
      {  }
   }
   
   public class Inner1B<U> : Outer<T>
   {
      U value2;
      
      public Inner1B(T value1, U value2) : base(value1)
      {
         this.value2 = value2;
      }
   }
}

public class Example
{
   public static void Main()
   {
      var inst1 = new Outer<String>("This");
      Console.WriteLine(inst1);
      
      var inst2 = new Outer<String>.Inner1A("Another");
      Console.WriteLine(inst2);
      
      var inst3 = new Outer<String>.Inner1B<int>("That", 2);
      Console.WriteLine(inst3);
   }
}
// The example displays the following output:
//       Outer`1[System.String]
//       Outer`1+Inner1A[System.String]
//       Outer`1+Inner1B`1[System.String,System.Int32]
<Assembly:CLSCompliant(True)>

Public Class Outer(Of T)
   Dim value As T
   
   Public Sub New(value As T)
      Me.value = value
   End Sub
   
   Public Class Inner1A : Inherits Outer(Of T)
      Public Sub New(value As T)
         MyBase.New(value)
      End Sub
   End Class
   
   Public Class Inner1B(Of U) : Inherits Outer(Of T)
      Dim value2 As U
      
      Public Sub New(value1 As T, value2 As U)
         MyBase.New(value1)
         Me.value2 = value2
      End Sub
   End Class
End Class

Public Module Example
   Public Sub Main()
      Dim inst1 As New Outer(Of String)("This")
      Console.WriteLine(inst1)
      
      Dim inst2 As New Outer(Of String).Inner1A("Another")
      Console.WriteLine(inst2)
      
      Dim inst3 As New Outer(Of String).Inner1B(Of Integer)("That", 2)
      Console.WriteLine(inst3)
   End Sub
End Module
' The example displays the following output:
'       Outer`1[System.String]
'       Outer`1+Inner1A[System.String]
'       Outer`1+Inner1B`1[System.String,System.Int32]

Názvy obecných typů jsou kódovány v názvu formuláře`n, kde název je název typu, ` je znakový literál a n je počet parametrů deklarovaných u typu, nebo pro vnořené obecné typy počet nově zavedených parametry typu.Generic type names are encoded in the form name`n, where name is the type name, ` is a character literal, and n is the number of parameters declared on the type, or, for nested generic types, the number of newly introduced type parameters. Toto kódování názvů obecného typu je primárně v zájmu vývojářů, kteří používají reflexi pro přístup k obecným typům specifikace CLS v knihovně.This encoding of generic type names is primarily of interest to developers who use reflection to access CLS-complaint generic types in a library.

Pokud jsou omezení aplikována na obecný typ, všechny typy použité jako omezení musí být také kompatibilní se specifikací CLS.If constraints are applied to a generic type, any types used as constraints must also be CLS-compliant. Následující příklad definuje třídu s názvem BaseClass, která není kompatibilní se specifikací CLS, a obecnou třídu s názvem BaseCollection, jejíž parametr typu musí být odvozen od BaseClass.The following example defines a class named BaseClass that is not CLS-compliant and a generic class named BaseCollection whose type parameter must derive from BaseClass. Vzhledem k tomu, že BaseClass není kompatibilní se specifikací CLS, kompilátor vygeneruje upozornění.But because BaseClass is not CLS-compliant, the compiler emits a warning.

using System;

[assembly:CLSCompliant(true)]

[CLSCompliant(false)] public class BaseClass
{}


public class BaseCollection<T> where T : BaseClass
{}
// Attempting to compile the example displays the following output:
//    warning CS3024: Constraint type 'BaseClass' is not CLS-compliant
<Assembly: CLSCompliant(True)>

<CLSCompliant(False)> Public Class BaseClass
End Class


Public Class BaseCollection(Of T As BaseClass)
End Class
' Attempting to compile the example displays the following output:
'    warning BC40040: Generic parameter constraint type 'BaseClass' is not 
'    CLS-compliant.
'    
'    Public Class BaseCollection(Of T As BaseClass)
'                                        ~~~~~~~~~

Je-li obecný typ odvozen od obecného základního typu, musí znovu deklarovat jakákoli omezení, aby bylo zaručeno, že jsou také splněna omezení základního typu.If a generic type is derived from a generic base type, it must redeclare any constraints so that it can guarantee that constraints on the base type are also satisfied. Následující příklad definuje Number<T>, který může představovat libovolný číselný typ.The following example defines a Number<T> that can represent any numeric type. Definuje také třídu FloatingPoint<T>, která představuje hodnotu s plovoucí desetinnou čárkou.It also defines a FloatingPoint<T> class that represents a floating point value. Zdrojový kód však nelze kompilovat, protože nepoužívá omezení pro Number<T> (Toto T musí být typ hodnoty) k FloatingPoint<T>.However, the source code fails to compile, because it does not apply the constraint on Number<T> (that T must be a value type) to FloatingPoint<T>.

using System;

[assembly:CLSCompliant(true)]

public class Number<T> where T : struct
{
   // use Double as the underlying type, since its range is a superset of
   // the ranges of all numeric types except BigInteger.
   protected double number;
      
   public Number(T value)
   {
      try {
         this.number = Convert.ToDouble(value);
      }  
      catch (OverflowException e) {
         throw new ArgumentException("value is too large.", e);
      }
      catch (InvalidCastException e) {
         throw new ArgumentException("The value parameter is not numeric.", e);
      }
   }

   public T Add(T value)
   {
      return (T) Convert.ChangeType(number + Convert.ToDouble(value), typeof(T));
   }

   public T Subtract(T value)
   {
      return (T) Convert.ChangeType(number - Convert.ToDouble(value), typeof(T));
   }
}
 
public class FloatingPoint<T> : Number<T> 
{
   public FloatingPoint(T number) : base(number) 
   {
      if (typeof(float) == number.GetType() ||
          typeof(double) == number.GetType() || 
          typeof(decimal) == number.GetType())
         this.number = Convert.ToDouble(number);
      else   
         throw new ArgumentException("The number parameter is not a floating-point number.");
   }       
}           
// The attempt to comple the example displays the following output:
//       error CS0453: The type 'T' must be a non-nullable value type in
//               order to use it as parameter 'T' in the generic type or method 'Number<T>'
<Assembly:CLSCompliant(True)>

Public Class Number(Of T As Structure)
   ' Use Double as the underlying type, since its range is a superset of
   ' the ranges of all numeric types except BigInteger.
   Protected number As Double
      
   Public Sub New(value As T)
      Try
         Me.number = Convert.ToDouble(value)
      Catch e As OverflowException
         Throw New ArgumentException("value is too large.", e)
      Catch e As InvalidCastException
         Throw New ArgumentException("The value parameter is not numeric.", e)
      End Try
   End Sub

   Public Function Add(value As T) As T
      Return CType(Convert.ChangeType(number + Convert.ToDouble(value), GetType(T)), T)
   End Function

   Public Function Subtract(value As T) As T
      Return CType(Convert.ChangeType(number - Convert.ToDouble(value), GetType(T)), T)
   End Function
End Class
 
Public Class FloatingPoint(Of T) : Inherits Number(Of T) 
   Public Sub New(number As T)
      MyBase.New(number) 
      If TypeOf number Is Single Or
               TypeOf number Is Double Or
               TypeOf number Is Decimal Then 
         Me.number = Convert.ToDouble(number)
      Else   
         throw new ArgumentException("The number parameter is not a floating-point number.")
      End If   
   End Sub       
End Class           
' The attempt to comple the example displays the following output:
'    error BC32105: Type argument 'T' does not satisfy the 'Structure'
'    constraint for type parameter 'T'.
'    
'    Public Class FloatingPoint(Of T) : Inherits Number(Of T)
'                                                          ~

Příklad se úspěšně zkompiluje, pokud je omezení přidáno do třídy FloatingPoint<T>.The example compiles successfully if the constraint is added to the FloatingPoint<T> class.

using System;

[assembly:CLSCompliant(true)]


public class Number<T> where T : struct
{
   // use Double as the underlying type, since its range is a superset of
   // the ranges of all numeric types except BigInteger.
   protected double number;
      
   public Number(T value)
   {
      try {
         this.number = Convert.ToDouble(value);
      }  
      catch (OverflowException e) {
         throw new ArgumentException("value is too large.", e);
      }
      catch (InvalidCastException e) {
         throw new ArgumentException("The value parameter is not numeric.", e);
      }
   }

   public T Add(T value)
   {
      return (T) Convert.ChangeType(number + Convert.ToDouble(value), typeof(T));
   }

   public T Subtract(T value)
   {
      return (T) Convert.ChangeType(number - Convert.ToDouble(value), typeof(T));
   }
}
 
public class FloatingPoint<T> : Number<T> where T : struct 
{
   public FloatingPoint(T number) : base(number) 
   {
      if (typeof(float) == number.GetType() ||
          typeof(double) == number.GetType() || 
          typeof(decimal) == number.GetType())
         this.number = Convert.ToDouble(number);
      else   
         throw new ArgumentException("The number parameter is not a floating-point number.");
   }       
}           
<Assembly:CLSCompliant(True)>

Public Class Number(Of T As Structure)
   ' Use Double as the underlying type, since its range is a superset of
   ' the ranges of all numeric types except BigInteger.
   Protected number As Double
      
   Public Sub New(value As T)
      Try
         Me.number = Convert.ToDouble(value)
      Catch e As OverflowException
         Throw New ArgumentException("value is too large.", e)
      Catch e As InvalidCastException
         Throw New ArgumentException("The value parameter is not numeric.", e)
      End Try
   End Sub

   Public Function Add(value As T) As T
      Return CType(Convert.ChangeType(number + Convert.ToDouble(value), GetType(T)), T)
   End Function

   Public Function Subtract(value As T) As T
      Return CType(Convert.ChangeType(number - Convert.ToDouble(value), GetType(T)), T)
   End Function
End Class
 
Public Class FloatingPoint(Of T As Structure) : Inherits Number(Of T) 
   Public Sub New(number As T)
      MyBase.New(number) 
      If TypeOf number Is Single Or
               TypeOf number Is Double Or
               TypeOf number Is Decimal Then 
         Me.number = Convert.ToDouble(number)
      Else   
         throw new ArgumentException("The number parameter is not a floating-point number.")
      End If   
   End Sub       
End Class           

Specifikace CLS (Common Language Specification) ukládá konzervativní model pro vytváření instancí pro vnořené typy a chráněné členy.The Common Language Specification imposes a conservative per-instantiation model for nested types and protected members. Otevřené obecné typy nemohou vystavovat pole nebo členy s podpisy, které obsahují konkrétní instanci vnořeného, chráněného obecného typu.Open generic types cannot expose fields or members with signatures that contain a specific instantiation of a nested, protected generic type. Neobecné typy, které rozšíří specifické instance obecné základní třídy nebo rozhraní, nemůžou vystavovat pole nebo členy s podpisy, které obsahují různé instance vnořeného, chráněného obecného typu.Non-generic types that extend a specific instantiation of a generic base class or interface cannot expose fields or members with signatures that contain a different instantiation of a nested, protected generic type.

Následující příklad definuje obecný typ, C1<T> (nebo C1(Of T) v Visual Basic) a chráněnou třídu C1<T>.N (nebo C1(Of T).N v Visual Basic).The following example defines a generic type, C1<T> (or C1(Of T) in Visual Basic), and a protected class, C1<T>.N (or C1(Of T).N in Visual Basic). C1<T> má dvě metody, M1 a M2.C1<T> has two methods, M1 and M2. M1 však není kompatibilní se specifikací CLS, protože se pokusí vrátit objekt C1<int>.N (nebo C1(Of Integer).N) z C1<T > (nebo C1(Of T)).However, M1 is not CLS-compliant because it tries to return a C1<int>.N (or C1(Of Integer).N) object from C1<T> (or C1(Of T)). Druhá třída, C2, je odvozena od C1<long> (nebo C1(Of Long)).A second class, C2, is derived from C1<long> (or C1(Of Long)). Má dvě metody M3 a M4.It has two methods, M3 and M4. M3 není kompatibilní se specifikací CLS, protože se pokusí vrátit objekt C1<int>.N (nebo C1(Of Integer).N) z podtřídy C1<long>.M3 is not CLS-compliant because it tries to return a C1<int>.N (or C1(Of Integer).N) object from a subclass of C1<long>. Všimněte si, že kompilátory jazyka mohou být ještě více omezující.Note that language compilers can be even more restrictive. V tomto příkladu Visual Basic při pokusu o kompilaci M4zobrazit chybu.In this example, Visual Basic displays an error when it tries to compile M4.

using System;

[assembly:CLSCompliant(true)]

public class C1<T> 
{
   protected class N { }

   protected void M1(C1<int>.N n) { } // Not CLS-compliant - C1<int>.N not
                                      // accessible from within C1<T> in all
                                      // languages
   protected void M2(C1<T>.N n) { }   // CLS-compliant – C1<T>.N accessible
                                      // inside C1<T>
}

public class C2 : C1<long> 
{
   protected void M3(C1<int>.N n) { }  // Not CLS-compliant – C1<int>.N is not
                                       // accessible in C2 (extends C1<long>)

   protected void M4(C1<long>.N n) { } // CLS-compliant, C1<long>.N is
                                       // accessible in C2 (extends C1<long>)
}
// Attempting to compile the example displays output like the following:
//       Generics4.cs(9,22): warning CS3001: Argument type 'C1<int>.N' is not CLS-compliant
//       Generics4.cs(18,22): warning CS3001: Argument type 'C1<int>.N' is not CLS-compliant
<Assembly:CLSCompliant(True)>

Public Class C1(Of T) 
   Protected Class N
   End Class

   Protected Sub M1(n As C1(Of Integer).N)   ' Not CLS-compliant - C1<int>.N not
                                             ' accessible from within C1(Of T) in all
   End Sub                                   ' languages


   Protected Sub M2(n As C1(Of T).N)     ' CLS-compliant – C1(Of T).N accessible
   End Sub                               ' inside C1(Of T)
End Class

Public Class C2 : Inherits C1(Of Long) 
   Protected Sub M3(n As C1(Of Integer).N)   ' Not CLS-compliant – C1(Of Integer).N is not
   End Sub                                   ' accessible in C2 (extends C1(Of Long))

   Protected Sub M4(n As C1(Of Long).N)   
   End Sub                                
End Class
' Attempting to compile the example displays output like the following:
'    error BC30508: 'n' cannot expose type 'C1(Of Integer).N' in namespace 
'    '<Default>' through class 'C1'.
'    
'       Protected Sub M1(n As C1(Of Integer).N)   ' Not CLS-compliant - C1<int>.N not
'                             ~~~~~~~~~~~~~~~~
'    error BC30389: 'C1(Of T).N' is not accessible in this context because 
'    it is 'Protected'.
'    
'       Protected Sub M3(n As C1(Of Integer).N)   ' Not CLS-compliant - C1(Of Integer).N is not
'    
'                             ~~~~~~~~~~~~~~~~
'    
'    error BC30389: 'C1(Of T).N' is not accessible in this context because it is 'Protected'.
'    
'       Protected Sub M4(n As C1(Of Long).N)  
'                             ~~~~~~~~~~~~~

KonstruktoryConstructors

Konstruktory v třídách a strukturách odpovídajících specifikaci CLS musí dodržovat tato pravidla:Constructors in CLS-compliant classes and structures must follow these rules:

  • Konstruktor odvozené třídy musí volat konstruktor instance své základní třídy před tím, než přistupuje k zděděným datům instance.A constructor of a derived class must call the instance constructor of its base class before it accesses inherited instance data. Tento požadavek je způsoben faktem, že konstruktory základní třídy nejsou děděny jejich odvozenými třídami.This requirement is due to the fact that base class constructors are not inherited by their derived classes. Toto pravidlo se nevztahuje na struktury, které nepodporují přímou dědičnost.This rule does not apply to structures, which do not support direct inheritance.

    Kompilátory obvykle toto pravidlo vynutil nezávisle na kompatibilitě se specifikací CLS, jak ukazuje následující příklad.Typically, compilers enforce this rule independently of CLS compliance, as the following example shows. Vytvoří třídu Doctor, která je odvozena od Person třídy, ale třída Doctor nemůže volat konstruktor třídy Person pro inicializaci zděděných polí instance.It creates a Doctor class that is derived from a Person class, but the Doctor class fails to call the Person class constructor to initialize inherited instance fields.

    using System;
    
    [assembly: CLSCompliant(true)]
    
    public class Person
    {
       private string fName, lName, _id;
       
       public Person(string firstName, string lastName, string id)
       {
          if (String.IsNullOrEmpty(firstName + lastName))
             throw new ArgumentNullException("Either a first name or a last name must be provided.");    
          
          fName = firstName;
          lName = lastName;
          _id = id;
       }
       
       public string FirstName 
       {
          get { return fName; }
       }
    
       public string LastName 
       {
          get { return lName; }
       }
       
       public string Id 
       {
          get { return _id; }
       }
    
       public override string ToString()
       {
          return String.Format("{0}{1}{2}", fName, 
                               String.IsNullOrEmpty(fName) ?  "" : " ",
                               lName);
       }
    }
    
    public class Doctor : Person
    {
       public Doctor(string firstName, string lastName, string id)
       {
       }
    
       public override string ToString()
       {
          return "Dr. " + base.ToString();
       }
    }
    // Attempting to compile the example displays output like the following:
    //    ctor1.cs(45,11): error CS1729: 'Person' does not contain a constructor that takes 0
    //            arguments
    //    ctor1.cs(10,11): (Location of symbol related to previous error)
    
    <Assembly: CLSCompliant(True)> 
    
    Public Class Person
       Private fName, lName, _id As String
       
       Public Sub New(firstName As String, lastName As String, id As String)
          If String.IsNullOrEmpty(firstName + lastName) Then
             Throw New ArgumentNullException("Either a first name or a last name must be provided.")    
          End If
          
          fName = firstName
          lName = lastName
          _id = id
       End Sub
       
       Public ReadOnly Property FirstName As String
          Get
             Return fName
          End Get
       End Property
    
       Public ReadOnly Property LastName As String
          Get
             Return lName
          End Get
       End Property
       
       Public ReadOnly Property Id As String
          Get
             Return _id
          End Get
       End Property
    
       Public Overrides Function ToString() As String
          Return String.Format("{0}{1}{2}", fName, 
                               If(String.IsNullOrEmpty(fName), "", " "),
                               lName)
       End Function
    End Class
    
    Public Class Doctor : Inherits Person
       Public Sub New(firstName As String, lastName As String, id As String)
       End Sub
    
       Public Overrides Function ToString() As String
          Return "Dr. " + MyBase.ToString()
       End Function
    End Class
    ' Attempting to compile the example displays output like the following:
    '    Ctor1.vb(46) : error BC30148: First statement of this 'Sub New' must be a call 
    '    to 'MyBase.New' or 'MyClass.New' because base class 'Person' of 'Doctor' does 
    '    not have an accessible 'Sub New' that can be called with no arguments.
    '    
    '       Public Sub New()
    '                  ~~~
    
  • Nelze volat konstruktor objektu s výjimkou vytvoření objektu.An object constructor cannot be called except to create an object. Kromě toho objekt nelze inicializovat dvakrát.In addition, an object cannot be initialized twice. Například to znamená, že metody Object.MemberwiseClone a deserializace, jako je BinaryFormatter.Deserialize nesmí volat konstruktory.For example, this means that Object.MemberwiseClone and deserialization methods such as BinaryFormatter.Deserialize must not call constructors.

VlastnostiProperties

Vlastnosti v typech odpovídajících specifikaci CLS musí dodržovat tato pravidla:Properties in CLS-compliant types must follow these rules:

  • Vlastnost musí mít metodu Setter, getter nebo obojí.A property must have a setter, a getter, or both. V sestavení jsou implementovány jako speciální metody, což znamená, že se zobrazí jako samostatné metody (getter má název get_PropertyName a metoda setter je set_PropertyName) označena jako SpecialName v sestavení mezipaměť.In an assembly, these are implemented as special methods, which means that they will appear as separate methods (the getter is named get_propertyname and the setter is set_propertyname) marked as SpecialName in the assembly's metadata. Kompilátory C# a Visual Basic vysazují toto pravidlo automaticky, aniž by bylo nutné použít atribut CLSCompliantAttribute.The C# and Visual Basic compilers enforce this rule automatically without the need to apply the CLSCompliantAttribute attribute.

  • Typ vlastnosti je návratový typ vlastnosti getter a poslední argument metody setter.A property's type is the return type of the property getter and the last argument of the setter. Tyto typy musí být kompatibilní se specifikací CLS a argumenty nelze přiřadit vlastnost odkazem (to znamená, že nemohou být spravovány ukazateli).These types must be CLS compliant, and arguments cannot be assigned to the property by reference (that is, they cannot be managed pointers).

  • Pokud má vlastnost metodu Getter i setter, musí obě být virtuální, obojí i obě instance.If a property has both a getter and a setter, they must both be virtual, both static, or both instance. Kompilátory C# a Visual Basic automaticky vynutil toto pravidlo pomocí jejich syntaxe definice vlastností.The C# and Visual Basic compilers automatically enforce this rule through their property definition syntax.

UdálostiEvents

Událost je definována podle jejího názvu a typu.An event is defined by its name and its type. Typ události je delegát, který se používá k označení události.The event type is a delegate that is used to indicate the event. Například událost AppDomain.AssemblyResolve je typu ResolveEventHandler.For example, the AppDomain.AssemblyResolve event is of type ResolveEventHandler. Kromě samotné události představují implementaci události tři metody s názvy založenými na názvu události a jsou v metadatech sestavení označeny jako SpecialName:In addition to the event itself, three methods with names based on the event name provide the event's implementation and are marked as SpecialName in the assembly's metadata:

  • Metoda pro přidání obslužné rutiny události s názvem add_EventName.A method for adding an event handler, named add_EventName. Například metoda odběru události pro událost AppDomain.AssemblyResolve má název add_AssemblyResolve.For example, the event subscription method for the AppDomain.AssemblyResolve event is named add_AssemblyResolve.

  • Metoda pro odebrání obslužné rutiny události s názvem remove_EventName.A method for removing an event handler, named remove_EventName. Například metoda odebrání pro událost AppDomain.AssemblyResolve má název remove_AssemblyResolve.For example, the removal method for the AppDomain.AssemblyResolve event is named remove_AssemblyResolve.

  • Metoda pro indikaci, že došlo k události s názvem raise_EventName.A method for indicating that the event has occurred, named raise_EventName.

Poznámka

Většina pravidel specifikace CLS (Common Language Specification) týkajících se událostí je implementována kompilátory jazyka a jsou transparentní pro vývojáře komponent.Most of the Common Language Specification's rules regarding events are implemented by language compilers and are transparent to component developers.

Metody pro přidání, odebrání a vyvolání události musí mít stejnou přístupnost.The methods for adding, removing, and raising the event must have the same accessibility. Musí také být všechny statické, instance nebo virtuální.They must also all be static, instance, or virtual. Metody pro přidání a odebrání události mají jeden parametr, jehož typ je typ delegáta události.The methods for adding and removing an event have one parameter whose type is the event delegate type. Metody Add a Remove musí být buď přítomné, nebo obě chybět.The add and remove methods must both be present or both be absent.

Následující příklad definuje třídu kompatibilní se specifikací CLS s názvem Temperature, která vyvolává událost TemperatureChanged, pokud se změna teploty mezi dvěma čteními rovná nebo překračuje prahovou hodnotu.The following example defines a CLS-compliant class named Temperature that raises a TemperatureChanged event if the change in temperature between two readings equals or exceeds a threshold value. Třída Temperature explicitně definuje metodu raise_TemperatureChanged, aby mohla selektivně provádět obslužné rutiny událostí.The Temperature class explicitly defines a raise_TemperatureChanged method so that it can selectively execute event handlers.

using System;
using System.Collections;
using System.Collections.Generic;

[assembly: CLSCompliant(true)]

public class TemperatureChangedEventArgs : EventArgs
{
   private Decimal originalTemp;
   private Decimal newTemp; 
   private DateTimeOffset when;
   
   public TemperatureChangedEventArgs(Decimal original, Decimal @new, DateTimeOffset time)
   {
      originalTemp = original;
      newTemp = @new;
      when = time;
   }   
   
   public Decimal OldTemperature
   {
      get { return originalTemp; }
   } 
   
   public Decimal CurrentTemperature
   {
      get { return newTemp; }
   } 
   
   public DateTimeOffset Time
   {
      get { return when; }
   }
}

public delegate void TemperatureChanged(Object sender, TemperatureChangedEventArgs e);

public class Temperature
{
   private struct TemperatureInfo
   {
      public Decimal Temperature;
      public DateTimeOffset Recorded;
   }
   
   public event TemperatureChanged TemperatureChanged;

   private Decimal previous;
   private Decimal current;
   private Decimal tolerance;
   private List<TemperatureInfo> tis = new List<TemperatureInfo>();
      
   public Temperature(Decimal temperature, Decimal tolerance)
   {
      current = temperature;
      TemperatureInfo ti = new TemperatureInfo();
      ti.Temperature = temperature;
      tis.Add(ti);
      ti.Recorded = DateTimeOffset.UtcNow;
      this.tolerance = tolerance;
   }
 
   public Decimal CurrentTemperature
   {
      get { return current; }
      set {
         TemperatureInfo ti = new TemperatureInfo();
         ti.Temperature = value;
         ti.Recorded = DateTimeOffset.UtcNow;
         previous = current;
         current = value;
         if (Math.Abs(current - previous) >= tolerance) 
            raise_TemperatureChanged(new TemperatureChangedEventArgs(previous, current, ti.Recorded));
      }
   }
   
   public void raise_TemperatureChanged(TemperatureChangedEventArgs eventArgs)
   {
      if (TemperatureChanged == null)
         return; 

      foreach (TemperatureChanged d in TemperatureChanged.GetInvocationList()) {
         if (d.Method.Name.Contains("Duplicate"))
            Console.WriteLine("Duplicate event handler; event handler not executed.");
         else
            d.Invoke(this, eventArgs);
      }
   }
}

public class Example
{
   public Temperature temp;
   
   public static void Main()
   {
      Example ex = new Example();
   }

   public Example()
   {
      temp = new Temperature(65, 3);
      temp.TemperatureChanged += this.TemperatureNotification;
      RecordTemperatures();
      Example ex = new Example(temp);
      ex.RecordTemperatures();
   }
      
   public Example(Temperature t)
   {
      temp = t;
      RecordTemperatures();
   }
   
   public void RecordTemperatures()
   {
      temp.TemperatureChanged += this.DuplicateTemperatureNotification;
      temp.CurrentTemperature = 66;
      temp.CurrentTemperature = 63;
   }
   
   internal void TemperatureNotification(Object sender, TemperatureChangedEventArgs e) 
   {
      Console.WriteLine("Notification 1: The temperature changed from {0} to {1}", e.OldTemperature, e.CurrentTemperature);   
   }
   
   public void DuplicateTemperatureNotification(Object sender, TemperatureChangedEventArgs e)
   { 
      Console.WriteLine("Notification 2: The temperature changed from {0} to {1}", e.OldTemperature, e.CurrentTemperature);   
   }
}
Imports System.Collections
Imports System.Collections.Generic

<Assembly: CLSCompliant(True)>

Public Class TemperatureChangedEventArgs   : Inherits EventArgs
   Private originalTemp As Decimal
   Private newTemp As Decimal 
   Private [when] As DateTimeOffset
   
   Public Sub New(original As Decimal, [new] As Decimal, [time] As DateTimeOffset)
      originalTemp = original
      newTemp = [new]
      [when] = [time]
   End Sub   
   
   Public ReadOnly Property OldTemperature As Decimal
      Get
         Return originalTemp
      End Get
   End Property 
   
   Public ReadOnly Property CurrentTemperature As Decimal
      Get
         Return newTemp
      End Get
   End Property 
   
   Public ReadOnly Property [Time] As DateTimeOffset
      Get
         Return [when]
      End Get
   End Property
End Class

Public Delegate Sub TemperatureChanged(sender As Object, e As TemperatureChangedEventArgs)

Public Class Temperature
   Private Structure TemperatureInfo
      Dim Temperature As Decimal
      Dim Recorded As DateTimeOffset
   End Structure
   
   Public Event TemperatureChanged As TemperatureChanged

   Private previous As Decimal
   Private current As Decimal
   Private tolerance As Decimal
   Private tis As New List(Of TemperatureInfo)
      
   Public Sub New(temperature As Decimal, tolerance As Decimal)
      current = temperature
      Dim ti As New TemperatureInfo()
      ti.Temperature = temperature
      ti.Recorded = DateTimeOffset.UtcNow
      tis.Add(ti)
      Me.tolerance = tolerance
   End Sub

   Public Property CurrentTemperature As Decimal
      Get
         Return current
      End Get
      Set
         Dim ti As New TemperatureInfo
         ti.Temperature = value
         ti.Recorded = DateTimeOffset.UtcNow
         previous = current
         current = value
         If Math.Abs(current - previous) >= tolerance Then
            raise_TemperatureChanged(New TemperatureChangedEventArgs(previous, current, ti.Recorded))
         End If
      End Set
   End Property
   
   Public Sub raise_TemperatureChanged(eventArgs As TemperatureChangedEventArgs)
      If TemperatureChangedEvent Is Nothing Then Exit Sub

      Dim ListenerList() As System.Delegate = TemperatureChangedEvent.GetInvocationList()
      For Each d As TemperatureChanged In TemperatureChangedEvent.GetInvocationList()
         If d.Method.Name.Contains("Duplicate") Then
            Console.WriteLine("Duplicate event handler; event handler not executed.")
         Else
            d.Invoke(Me, eventArgs)
         End If
      Next
   End Sub
End Class

Public Class Example
   Public WithEvents temp As Temperature
   
   Public Shared Sub Main()
      Dim ex As New Example()
   End Sub

   Public Sub New()
      temp = New Temperature(65, 3)
      RecordTemperatures()
      Dim ex As New Example(temp)
      ex.RecordTemperatures()
   End Sub
      
   Public Sub New(t As Temperature)
      temp = t
      RecordTemperatures()
   End Sub
   
   Public Sub RecordTemperatures()
      temp.CurrentTemperature = 66
      temp.CurrentTemperature = 63
   
   End Sub
   
   Friend Shared Sub TemperatureNotification(sender As Object, e As TemperatureChangedEventArgs) _
          Handles temp.TemperatureChanged
      Console.WriteLine("Notification 1: The temperature changed from {0} to {1}", e.OldTemperature, e.CurrentTemperature)   
   End Sub
   
   Friend Shared Sub DuplicateTemperatureNotification(sender As Object, e As TemperatureChangedEventArgs) _
          Handles temp.TemperatureChanged
      Console.WriteLine("Notification 2: The temperature changed from {0} to {1}", e.OldTemperature, e.CurrentTemperature)   
   End Sub
End Class

PřetíženíOverloads

Specifikace CLS (Common Language Specification) ukládá následující požadavky na přetížené členy:The Common Language Specification imposes the following requirements on overloaded members:

  • Členy mohou být přetíženy na základě počtu parametrů a typu libovolného parametru.Members can be overloaded based on the number of parameters and the type of any parameter. Konvence volání, návratový typ, vlastní modifikátory použité pro metodu nebo její parametr a zda jsou parametry předány hodnotou nebo odkazem, se nepovažují za rozdíl mezi přetíženími.Calling convention, return type, custom modifiers applied to the method or its parameter, and whether parameters are passed by value or by reference are not considered when differentiating between overloads. Příklad naleznete v kódu pro požadavek, aby názvy musí být jedinečné v rámci oboru v části konvence pojmenování .For an example, see the code for the requirement that names must be unique within a scope in the Naming conventions section.

  • Pouze vlastnosti a metody mohou být přetíženy.Only properties and methods can be overloaded. Pole a události nemohou být přetíženy.Fields and events cannot be overloaded.

  • Obecné metody mohou být přetíženy na základě počtu jejich obecných parametrů.Generic methods can be overloaded based on the number of their generic parameters.

Poznámka

Operátory op_Explicit a op_Implicit jsou výjimky na pravidlo, které návratová hodnota není považována za součást signatury metody pro řešení přetížení.The op_Explicit and op_Implicit operators are exceptions to the rule that return value is not considered part of a method signature for overload resolution. Tyto dva operátory mohou být přetíženy v závislosti na jejich parametrech a jejich návratové hodnotě.These two operators can be overloaded based on both their parameters and their return value.

VýjimkyExceptions

Objekty výjimky musí být odvozeny od System.Exception nebo z jiného typu odvozeného z System.Exception.Exception objects must derive from System.Exception or from another type derived from System.Exception. Následující příklad ukazuje chybu kompilátoru, která je výsledkem, když je použita vlastní třída s názvem ErrorClass pro zpracování výjimek.The following example illustrates the compiler error that results when a custom class named ErrorClass is used for exception handling.

using System;

[assembly: CLSCompliant(true)]

public class ErrorClass
{ 
   string msg;
   
   public ErrorClass(string errorMessage)
   {
      msg = errorMessage;
   }
   
   public string Message
   {
      get { return msg; }
   }
}

public static class StringUtilities
{
   public static string[] SplitString(this string value, int index)
   {
      if (index < 0 | index > value.Length) {
         ErrorClass badIndex = new ErrorClass("The index is not within the string.");
         throw badIndex;
      }
      string[] retVal = { value.Substring(0, index - 1), 
                          value.Substring(index) };
      return retVal;
   }
}
// Compilation produces a compiler error like the following:
//    Exceptions1.cs(26,16): error CS0155: The type caught or thrown must be derived from
//            System.Exception
Imports System.Runtime.CompilerServices

<Assembly: CLSCompliant(True)>
 
Public Class ErrorClass 
   Dim msg As String
   
   Public Sub New(errorMessage As String)
      msg = errorMessage
   End Sub
   
   Public ReadOnly Property Message As String
      Get
         Return msg
      End Get   
   End Property
End Class

Public Module StringUtilities
   <Extension()> Public Function SplitString(value As String, index As Integer) As String()
      If index < 0 Or index > value.Length Then
         Dim BadIndex As New ErrorClass("The index is not within the string.")
         Throw BadIndex
      End If
      Dim retVal() As String = { value.Substring(0, index - 1), 
                                 value.Substring(index) }
      Return retVal
   End Function
End Module
' Compilation produces a compiler error like the following:
'    Exceptions1.vb(27) : error BC30665: 'Throw' operand must derive from 'System.Exception'.
'    
'             Throw BadIndex
'             ~~~~~~~~~~~~~~

Chcete-li tuto chybu opravit, třída ErrorClass musí dědit z System.Exception.To correct this error, the ErrorClass class must inherit from System.Exception. Kromě toho musí být přepsána vlastnost Message.In addition, the Message property must be overridden. Následující příklad opravuje tyto chyby k definování ErrorClass třídy, která je kompatibilní se specifikací CLS.The following example corrects these errors to define an ErrorClass class that is CLS-compliant.

using System;

[assembly: CLSCompliant(true)]

public class ErrorClass : Exception
{ 
   string msg;
   
   public ErrorClass(string errorMessage)
   {
      msg = errorMessage;
   }
   
   public override string Message
   {
      get { return msg; }
   }
}

public static class StringUtilities
{
   public static string[] SplitString(this string value, int index)
   {
      if (index < 0 | index > value.Length) {
         ErrorClass badIndex = new ErrorClass("The index is not within the string.");
         throw badIndex;
      }
      string[] retVal = { value.Substring(0, index - 1), 
                          value.Substring(index) };
      return retVal;
   }
}
Imports System.Runtime.CompilerServices

<Assembly: CLSCompliant(True)>
 
Public Class ErrorClass : Inherits Exception
   Dim msg As String
   
   Public Sub New(errorMessage As String)
      msg = errorMessage
   End Sub
   
   Public Overrides ReadOnly Property Message As String
      Get
         Return msg
      End Get   
   End Property
End Class

Public Module StringUtilities
   <Extension()> Public Function SplitString(value As String, index As Integer) As String()
      If index < 0 Or index > value.Length Then
         Dim BadIndex As New ErrorClass("The index is not within the string.")
         Throw BadIndex
      End If
      Dim retVal() As String = { value.Substring(0, index - 1), 
                                 value.Substring(index) }
      Return retVal
   End Function
End Module

AtributyAttributes

Sestavení rozhraní In.NET, vlastní atributy poskytují rozšiřitelný mechanismus pro ukládání vlastních atributů a načítání metadat o programovacích objektech, jako jsou sestavení, typy, členy a parametry metody.In.NET Framework assemblies, custom attributes provide an extensible mechanism for storing custom attributes and retrieving metadata about programming objects, such as assemblies, types, members, and method parameters. Vlastní atributy se musí odvozovat z System.Attribute nebo z typu odvozeného z System.Attribute.Custom attributes must derive from System.Attribute or from a type derived from System.Attribute.

V následujícím příkladu je toto pravidlo porušeno.The following example violates this rule. Definuje třídu NumericAttribute, která není odvozena od System.Attribute.It defines a NumericAttribute class that does not derive from System.Attribute. Všimněte si, že chyba kompilátoru je výsledkem pouze v případě, že je použit atribut, který není kompatibilní se specifikací CLS, nikoli při definování třídy.Note that a compiler error results only when the non-CLS-compliant attribute is applied, not when the class is defined.

using System;

[assembly: CLSCompliant(true)]

[AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Struct)] 
public class NumericAttribute
{
   private bool _isNumeric;
   
   public NumericAttribute(bool isNumeric)
   {
      _isNumeric = isNumeric;
   }
   
   public bool IsNumeric 
   {
      get { return _isNumeric; }
   }
}

[Numeric(true)] public struct UDouble
{
   double Value;
}
// Compilation produces a compiler error like the following:
//    Attribute1.cs(22,2): error CS0616: 'NumericAttribute' is not an attribute class
//    Attribute1.cs(7,14): (Location of symbol related to previous error)
<Assembly: CLSCompliant(True)>

<AttributeUsageAttribute(AttributeTargets.Class Or AttributeTargets.Struct)> _
Public Class NumericAttribute
   Private _isNumeric As Boolean
   
   Public Sub New(isNumeric As Boolean)
      _isNumeric = isNumeric
   End Sub
   
   Public ReadOnly Property IsNumeric As Boolean
      Get
         Return _isNumeric
      End Get
   End Property
End Class

<Numeric(True)> Public Structure UDouble
   Dim Value As Double
End Structure
' Compilation produces a compiler error like the following:
'    error BC31504: 'NumericAttribute' cannot be used as an attribute because it 
'    does not inherit from 'System.Attribute'.
'    
'    <Numeric(True)> Public Structure UDouble
'     ~~~~~~~~~~~~~

Konstruktor nebo vlastnosti atributu kompatibilního se specifikací CLS mohou vystavovat pouze následující typy:The constructor or the properties of a CLS-compliant attribute can expose only the following types:

Následující příklad definuje třídu DescriptionAttribute, která je odvozena z Attribute.The following example defines a DescriptionAttribute class that derives from Attribute. Konstruktor třídy má parametr typu Descriptor, takže třída není kompatibilní se specifikací CLS.The class constructor has a parameter of type Descriptor, so the class is not CLS-compliant. Všimněte si, C# že kompilátor generuje upozornění, ale zkompiluje úspěšně, zatímco kompilátor Visual Basic emituje ani upozornění, ani chybu.Note that the C# compiler emits a warning but compiles successfully, whereas the Visual Basic compiler emits neither a warning nor an error.

using System;

[assembly:CLSCompliantAttribute(true)]

public enum DescriptorType { type, member };

public class Descriptor
{
   public DescriptorType Type;
   public String Description; 
}

[AttributeUsage(AttributeTargets.All)]
public class DescriptionAttribute : Attribute
{
   private Descriptor desc;
   
   public DescriptionAttribute(Descriptor d)
   {
      desc = d; 
   }
   
   public Descriptor Descriptor
   { get { return desc; } } 
}
// Attempting to compile the example displays output like the following:
//       warning CS3015: 'DescriptionAttribute' has no accessible
//               constructors which use only CLS-compliant types
<Assembly:CLSCompliantAttribute(True)>

Public Enum DescriptorType As Integer
   Type = 0
   Member = 1
End Enum

Public Class Descriptor
   Public Type As DescriptorType 
   Public Description As String 
End Class

<AttributeUsage(AttributeTargets.All)> _
Public Class DescriptionAttribute : Inherits Attribute
   Private desc As Descriptor
   
   Public Sub New(d As Descriptor)
      desc = d 
   End Sub
   
   Public ReadOnly Property Descriptor As Descriptor
      Get 
         Return desc
      End Get    
   End Property
End Class

Atribut CLSCompliantAttributeThe CLSCompliantAttribute attribute

Atribut CLSCompliantAttribute slouží k označení, zda prvek programu vyhovuje specifikaci CLS (Common Language Specification).The CLSCompliantAttribute attribute is used to indicate whether a program element complies with the Common Language Specification. Konstruktor CLSCompliantAttribute.CLSCompliantAttribute(Boolean) obsahuje jeden povinný parametr isCompliant, který označuje, zda je prvek program kompatibilní se specifikací CLS.The CLSCompliantAttribute.CLSCompliantAttribute(Boolean) constructor includes a single required parameter, isCompliant, that indicates whether the program element is CLS-compliant.

V době kompilace kompilátor detekuje nekompatibilní prvky, které se považují za kompatibilní se specifikací CLS, a vygeneruje upozornění.At compile time, the compiler detects non-compliant elements that are presumed to be CLS-compliant and emits a warning. Kompilátor negeneruje upozornění pro typy nebo členy, které jsou explicitně deklarovány tak, že nejsou kompatibilní.The compiler does not emit warnings for types or members that are explicitly declared to be non-compliant.

Vývojáři komponent mohou použít atribut CLSCompliantAttribute dvěma způsoby:Component developers can use the CLSCompliantAttribute attribute in two ways:

  • Pro definování částí veřejného rozhraní vystaveného komponentou, která je kompatibilní se specifikací CLS, a částí, které nejsou kompatibilní se specifikací CLS.To define the parts of the public interface exposed by a component that are CLS-compliant and the parts that are not CLS-compliant. Když je atribut použit k označení určitých prvků programu jako kompatibilní se specifikací CLS, jeho použití zaručuje, že tyto prvky jsou přístupné ze všech jazyků a nástrojů, které cílí na .NET Framework.When the attribute is used to mark particular program elements as CLS-compliant, its use guarantees that those elements are accessible from all languages and tools that target the .NET Framework.

  • Aby bylo zajištěno, že veřejné rozhraní knihovny součástí zpřístupňuje pouze prvky programu, které jsou kompatibilní se specifikací CLS.To ensure that the component library's public interface exposes only program elements that are CLS-compliant. Pokud prvky nejsou kompatibilní se specifikací CLS, kompilátory většinou vystaví upozornění.If elements are not CLS-compliant, compilers will generally issue a warning.

Varování

V některých případech vynutily jazykové kompilátory pravidla kompatibilní se specifikací CLS bez ohledu na to, zda je použit atribut CLSCompliantAttribute.In some cases, language compilers enforce CLS-compliant rules regardless of whether the CLSCompliantAttribute attribute is used. Například definování statického člena v rozhraní narušuje pravidlo specifikace CLS.For example, defining a static member in an interface violates a CLS rule. V tomto ohledu, pokud definujete člena static (in C#) nebo Shared (v Visual Basic) v rozhraní, kompilátory C# a Visual Basic zobrazí chybovou zprávu a aplikace nebude zkompilována.In this regard, if you define a static (in C#) or Shared (in Visual Basic) member in an interface, both the C# and Visual Basic compilers display an error message and fail to compile the app.

Atribut CLSCompliantAttribute je označen atributem AttributeUsageAttribute, který má hodnotu AttributeTargets.All.The CLSCompliantAttribute attribute is marked with an AttributeUsageAttribute attribute that has a value of AttributeTargets.All. Tato hodnota umožňuje použít atribut CLSCompliantAttribute pro libovolný prvek programu, včetně sestavení, modulů, typů (tříd, struktur, výčtů, rozhraní a delegátů), členů typu (konstruktory, metody, vlastnosti, pole a události), parametry, Obecné parametry a návratové hodnoty.This value allows you to apply the CLSCompliantAttribute attribute to any program element, including assemblies, modules, types (classes, structures, enumerations, interfaces, and delegates), type members (constructors, methods, properties, fields, and events), parameters, generic parameters, and return values. Nicméně v praxi byste měli použít atribut pouze pro sestavení, typy a členy typu.However, in practice, you should apply the attribute only to assemblies, types, and type members. V opačném případě kompilátory ignorují atribut a pokračují v generování upozornění kompilátoru pokaždé, když narazí na nekompatibilní parametr, obecný parametr nebo návratovou hodnotu ve veřejném rozhraní knihovny.Otherwise, compilers ignore the attribute and continue to generate compiler warnings whenever they encounter a non-compliant parameter, generic parameter, or return value in your library's public interface.

Hodnota atributu CLSCompliantAttribute dědí z obsažených prvků programu.The value of the CLSCompliantAttribute attribute is inherited by contained program elements. Například pokud je sestavení označeno jako kompatibilní se specifikací CLS, jeho typy jsou také kompatibilní se specifikací CLS.For example, if an assembly is marked as CLS-compliant, its types are also CLS-compliant. Pokud je typ označený jako kompatibilní se specifikací CLS, jeho vnořené typy a členy jsou také kompatibilní se specifikací CLS.If a type is marked as CLS-compliant, its nested types and members are also CLS-compliant.

Zděděné dodržování předpisů lze explicitně přepsat použitím atributu CLSCompliantAttribute pro obsažený programový prvek.You can explicitly override the inherited compliance by applying the CLSCompliantAttribute attribute to a contained program element. Například můžete použít atribut CLSCompliantAttribute s isCompliant hodnotou false k definování nekompatibilního typu v vyhovujícím sestavení a můžete použít atribut s isCompliant hodnotou true k definování kompatibilního typu v sestavení, které nedodržuje předpisy.For example, you can use the CLSCompliantAttribute attribute with an isCompliant value of false to define a non-compliant type in a compliant assembly, and you can use the attribute with an isCompliant value of true to define a compliant type in a non-compliant assembly. Můžete také definovat nekompatibilní členy v typu, který odpovídá.You can also define non-compliant members in a compliant type. Nevyhovující typ ale nemůže mít odpovídající členy, takže nemůžete použít atribut s isCompliant hodnotou true k přepsání dědění z nekompatibilního typu.However, a non-compliant type cannot have compliant members, so you cannot use the attribute with an isCompliant value of true to override inheritance from a non-compliant type.

Při vývoji komponent byste vždy měli použít atribut CLSCompliantAttribute k označení, zda vaše sestavení, jeho typy a jeho členové jsou kompatibilní se specifikací CLS.When you are developing components, you should always use the CLSCompliantAttribute attribute to indicate whether your assembly, its types, and its members are CLS-compliant.

Vytvoření součástí odpovídajících specifikaci CLS:To create CLS-compliant components:

  1. Pomocí CLSCompliantAttribute označíte sestavení jako kompatibilní se specifikací CLS.Use the CLSCompliantAttribute to mark you assembly as CLS-compliant.

  2. Označte všechny veřejně vystavené typy v sestavení, které nejsou kompatibilní se specifikací CLS, jako nevyhovující.Mark any publicly exposed types in the assembly that are not CLS-compliant as non-compliant.

  3. Označte všechny veřejně vystavené členy v typech kompatibilních se specifikací CLS jako nevyhovující.Mark any publicly exposed members in CLS-compliant types as non-compliant.

  4. Poskytněte alternativu kompatibilní se specifikací CLS pro členy, které nedodržují specifikaci CLS.Provide a CLS-compliant alternative for non-CLS-compliant members.

Pokud jste úspěšně označili všechny typy a členy, které nedodržují předpisy, kompilátor by neměl generovat žádná upozornění, která nedodržují předpisy.If you've successfully marked all your non-compliant types and members, your compiler should not emit any non-compliance warnings. Měli byste však určit, kteří členové nejsou kompatibilní se specifikací CLS, a seznamte se s alternativami kompatibilními se specifikací CLS v dokumentaci k produktu.However, you should indicate which members are not CLS-compliant and list their CLS-compliant alternatives in your product documentation.

Následující příklad používá atribut CLSCompliantAttribute k definování sestavení kompatibilního se specifikací CLS a typu, CharacterUtilities, který má dva členy nekompatibilní se specifikací CLS.The following example uses the CLSCompliantAttribute attribute to define a CLS-compliant assembly and a type, CharacterUtilities, that has two non-CLS-compliant members. Vzhledem k tomu, že oba členy jsou označeny atributem CLSCompliant(false), kompilátor nevydá žádná upozornění.Because both members are tagged with the CLSCompliant(false) attribute, the compiler produces no warnings. Třída také poskytuje alternativu odpovídající specifikaci CLS pro obě metody.The class also provides a CLS-compliant alternative for both methods. Obvykle bychom přidali dvě přetížení do metody ToUTF16 pro zajištění alternativ odpovídajících specifikaci CLS.Ordinarily, we would just add two overloads to the ToUTF16 method to provide CLS-compliant alternatives. Nicméně vzhledem k tomu, že metody nemohou být přetíženy na základě návratové hodnoty, názvy metod odpovídajících specifikaci CLS se liší od názvů nevyhovujících metod.However, because methods cannot be overloaded based on return value, the names of the CLS-compliant methods are different from the names of the non-compliant methods.

using System;
using System.Text;

[assembly:CLSCompliant(true)]

public class CharacterUtilities
{
   [CLSCompliant(false)] public static ushort ToUTF16(String s)
   {
      s = s.Normalize(NormalizationForm.FormC);
      return Convert.ToUInt16(s[0]);
   }

   [CLSCompliant(false)] public static ushort ToUTF16(Char ch)
   {
      return Convert.ToUInt16(ch); 
   }
      
   // CLS-compliant alternative for ToUTF16(String).
   public static int ToUTF16CodeUnit(String s)
   {
      s = s.Normalize(NormalizationForm.FormC);
      return (int) Convert.ToUInt16(s[0]);
   }

   // CLS-compliant alternative for ToUTF16(Char).
   public static int ToUTF16CodeUnit(Char ch)
   {
      return Convert.ToInt32(ch);
   }

   public bool HasMultipleRepresentations(String s)
   {
      String s1 = s.Normalize(NormalizationForm.FormC);
      return s.Equals(s1);   
   }

   public int GetUnicodeCodePoint(Char ch)
   {
      if (Char.IsSurrogate(ch))
         throw new ArgumentException("ch cannot be a high or low surrogate.");

      return Char.ConvertToUtf32(ch.ToString(), 0);   
   }
   
   public int GetUnicodeCodePoint(Char[] chars)
   {
      if (chars.Length > 2)
         throw new ArgumentException("The array has too many characters.");

      if (chars.Length == 2) {
         if (! Char.IsSurrogatePair(chars[0], chars[1]))
            throw new ArgumentException("The array must contain a low and a high surrogate.");
         else
            return Char.ConvertToUtf32(chars[0], chars[1]);
      }
      else {
         return Char.ConvertToUtf32(chars.ToString(), 0);
      } 
   }
}
Imports System.Text

<Assembly:CLSCompliant(True)>

Public Class CharacterUtilities
   <CLSCompliant(False)> Public Shared Function ToUTF16(s As String) As UShort
      s = s.Normalize(NormalizationForm.FormC)
      Return Convert.ToUInt16(s(0))
   End Function

   <CLSCompliant(False)> Public Shared Function ToUTF16(ch As Char) As UShort
      Return Convert.ToUInt16(ch) 
   End Function
      
   ' CLS-compliant alternative for ToUTF16(String).
   Public Shared Function ToUTF16CodeUnit(s As String) As Integer
      s = s.Normalize(NormalizationForm.FormC)
      Return CInt(Convert.ToInt16(s(0)))
   End Function

   ' CLS-compliant alternative for ToUTF16(Char).
   Public Shared Function ToUTF16CodeUnit(ch As Char) As Integer
      Return Convert.ToInt32(ch)
   End Function

   Public Function HasMultipleRepresentations(s As String) As Boolean
      Dim s1 As String = s.Normalize(NormalizationForm.FormC)
      Return s.Equals(s1)   
   End Function

   Public Function GetUnicodeCodePoint(ch As Char) As Integer
      If Char.IsSurrogate(ch) Then
         Throw New ArgumentException("ch cannot be a high or low surrogate.")
      End If
      Return Char.ConvertToUtf32(ch.ToString(), 0)   
   End Function
   
   Public Function GetUnicodeCodePoint(chars() As Char) As Integer
      If chars.Length > 2 Then
         Throw New ArgumentException("The array has too many characters.")
      End If
      If chars.Length = 2 Then
         If Not Char.IsSurrogatePair(chars(0), chars(1)) Then
            Throw New ArgumentException("The array must contain a low and a high surrogate.")
         Else
            Return Char.ConvertToUtf32(chars(0), chars(1))
         End If
      Else
         Return Char.ConvertToUtf32(chars.ToString(), 0)
      End If 
   End Function            
End Class

Pokud vyvíjíte aplikaci místo knihovny (tj. Pokud nezveřejňujete typy nebo členy, které mohou být spotřebovány jinými vývojáři aplikací), dodržování předpisů CLS prvků programu, které vaše aplikace spotřebovává, je důležité pouze v případě, že je váš jazyk nepodporuje. .If you are developing an app rather than a library (that is, if you aren't exposing types or members that can be consumed by other app developers), the CLS compliance of the program elements that your app consumes are of interest only if your language does not support them. V takovém případě kompilátor jazyka vygeneruje chybu, pokud se pokusíte použít element, který není kompatibilní se specifikací CLS.In that case, your language compiler will generate an error when you try to use a non-CLS-compliant element.

Vzájemná funkční spolupráce mezi jazykyCross-Language Interoperability

Jazyková nezávislost má několik možných významů.Language independence has a number of possible meanings. Jeden z nich, který je popsaný v článku nezávislá na Nezávislostech jazyka a jazykově nezávislé součásti, zahrnuje plynulé využívání typů napsaných v jednom jazyce z aplikace napsané v jiném jazyce.One meaning, which is discussed in the article Language Independence and Language-Independent Components, involves seamlessly consuming types written in one language from an app written in another language. Druhý význam, který je hlavním cílem tohoto článku, zahrnuje sloučení kódu napsaného ve více jazycích do jediného sestavení rozhraní .NET Framework.A second meaning, which is the focus of this article, involves combining code written in multiple languages into a single .NET Framework assembly.

Následující příklad znázorňuje interoperabilitu mezi jazyky vytvořením knihovny tříd s názvem Utilities.dll, která obsahuje dvě třídy NumericLib a StringLib.The following example illustrates cross-language interoperability by creating a class library named Utilities.dll that includes two classes, NumericLib and StringLib. Třída NumericLib je napsána v jazyce C# a třída StringLib je napsána v jazyce Visual Basic.The NumericLib class is written in C#, and the StringLib class is written in Visual Basic. Zde je zdrojový kód pro StringUtil.vb, který obsahuje jeden člen, ToTitleCase, ve své třídě StringLib.Here's the source code for StringUtil.vb, which includes a single member, ToTitleCase, in its StringLib class.

Imports System.Collections.Generic
Imports System.Runtime.CompilerServices

Public Module StringLib
   Private exclusions As List(Of String) 
   
   Sub New()
      Dim words() As String = { "a", "an", "and", "of", "the" }
      exclusions = New List(Of String)
      exclusions.AddRange(words)
   End Sub
   
   <Extension()> _
   Public Function ToTitleCase(title As String) As String
      Dim words() As String = title.Split() 
      Dim result As String = String.Empty
      
      For ctr As Integer = 0 To words.Length - 1
         Dim word As String = words(ctr)
         If ctr = 0 OrElse Not exclusions.Contains(word.ToLower()) Then
            result += word.Substring(0, 1).ToUpper() + _
                      word.Substring(1).ToLower()
         Else
            result += word.ToLower()
         End If
         If ctr <= words.Length - 1 Then
            result += " "             
         End If   
      Next 
      Return result 
   End Function
End Module

Zde je zdrojový kód pro NumberUtil.cs, který definuje třídu NumericLib se dvěma členy IsEven a NearZero.Here's the source code for NumberUtil.cs, which defines a NumericLib class that has two members, IsEven and NearZero.

using System;

public static class NumericLib 
{
   public static bool IsEven(this IConvertible number)
   {
      if (number is Byte ||
          number is SByte ||
          number is Int16 ||
          number is UInt16 || 
          number is Int32 || 
          number is UInt32 ||
          number is Int64)
         return Convert.ToInt64(number) % 2 == 0;
      else if (number is UInt64)
         return ((ulong) number) % 2 == 0;
      else
         throw new NotSupportedException("IsEven called for a non-integer value.");
   }
   
   public static bool NearZero(double number)
   {
      return Math.Abs(number) < .00001; 
   }
}

Chcete-li zabalit dvě třídy do jednoho sestavení, musíte je zkompilovat do modulů.To package the two classes in a single assembly, you must compile them into modules. Pro kompilaci zdrojového kódu jazyka Visual Basic do modulu použijte tento příkaz:To compile the Visual Basic source code file into a module, use this command:

vbc /t:module StringUtil.vb

Další informace o syntaxi příkazového řádku kompilátoru Visual Basic naleznete v tématu sestavování z příkazového řádku.For more information about the command-line syntax of the Visual Basic compiler, see Building from the Command Line.

Pro kompilaci zdrojového kódu jazyka C# do modulu použijte tento příkaz:To compile the C# source code file into a module, use this command:

csc /t:module NumberUtil.cs

Další informace o syntaxi příkazového řádku C# kompilátoru najdete v tématu sestavování z příkazového řádku pomocí CSc. exe.For more information about the command-line syntax of the C# compiler, see Command-line Building With csc.exe.

Pak použijte Možnosti linkeru ke kompilaci dvou modulů do sestavení:You then use the Linker options to compile the two modules into an assembly:

link numberutil.netmodule stringutil.netmodule /out:UtilityLib.dll /dll

Následující příklad následně volá metody NumericLib.NearZero a StringLib.ToTitleCase.The following example then calls the NumericLib.NearZero and StringLib.ToTitleCase methods. Kód jazyka Visual Basic i kód jazyka C# může přistupovat k metodám v obou třídách.Note that both the Visual Basic code and the C# code are able to access the methods in both classes.

using System;

public class Example
{
   public static void Main()
   {
      Double dbl = 0.0 - Double.Epsilon;
      Console.WriteLine(NumericLib.NearZero(dbl));
      
      string s = "war and peace";
      Console.WriteLine(s.ToTitleCase());
   }
}
// The example displays the following output:
//       True
//       War and Peace
Module Example
   Public Sub Main()
      Dim dbl As Double = 0.0 - Double.Epsilon
      Console.WriteLine(NumericLib.NearZero(dbl))
      
      Dim s As String = "war and peace"
      Console.WriteLine(s.ToTitleCase())
   End Sub
End Module
' The example displays the following output:
'       True
'       War and Peace

Pro kompilaci kódu jazyka Visual Basic použijte tento příkaz:To compile the Visual Basic code, use this command:

vbc example.vb /r:UtilityLib.dll

Chcete-li C#kompilovat s, změňte název kompilátoru z Vbc na CSCa změňte příponu souboru z. vb na. cs:To compile with C#, change the name of the compiler from vbc to csc, and change the file extension from .vb to .cs:

csc example.cs /r:UtilityLib.dll

Viz také:See also