Home Random Page


CATEGORIES:

BiologyChemistryConstructionCultureEcologyEconomyElectronicsFinanceGeographyHistoryInformaticsLawMathematicsMechanicsMedicineOtherPedagogyPhilosophyPhysicsPolicyPsychologySociologySportTourism






Nbsp;   Type Visibility

When defining a type at file scope (versus defining a type nested within another type), you can specify the type’s visibility as being either public or internal. A public type is visible to all code within the defining assembly as well as all code written in other assemblies. An internal type is visible to all code within the defining assembly, and the type is not visible to code written in other assemblies. If you do not explicitly specify either of these when you define a type, the C# compiler sets the type’s visibility to internal (the more restrictive of the two). Here are some examples.

 



using System;

 



// The type below has public visibility and can be accessed by code

// in this assembly as well as code written in other assemblies. public class ThisIsAPublicType { ... }

 



// The type below has internal visibility and can be accessed by code

// in this assembly only.

internal class ThisIsAnInternalType { ... }

 



// The type below is internal because public/internal

// is not explicitly stated.

class ThisIsAlsoAnInternalType { ... }

 



Friend Assemblies

Imagine the following scenario: a company has one team, TeamA, that is defining a bunch of utility types in one assembly, and they expect these types to be used by members in another team, TeamB. For various reasons such as time schedules or geographical location, or perhaps different cost centers or reporting structures, these two teams cannot build all of their types into a single assembly; instead, each team produces its own assembly file.


In order for TeamB’s assembly to use TeamA’s types, TeamA must define all of their utility types as public. However, this means that their types are publicly visible to any and all assemblies; develop- ers in another company could write code that uses the public utility types, and this is not desirable. Maybe the utility types make certain assumptions that TeamB ensures when they write code that uses TeamA’s types. What we’d like to have is a way for TeamA to define their types as internal while still allowing TeamB to access the types. The CLR and C# support this via friend assemblies. This friend as- sembly feature is also useful when you want to have one assembly containing code that performs unit tests against the internal types within another assembly.

When an assembly is built, it can indicate other assemblies it considers “friends” by using the InternalsVisibleTo attribute defined in the System.Runtime.CompilerServices namespace. The attribute has a string parameter that identifies the friend assembly’s name and public key (the string you pass to the attribute must not include a version, culture, or processor architecture). Note that friend assemblies can access all of an assembly’s internal types as well as these type’s internal members. Here is an example of how an assembly can specify two other strongly named assemblies named “Wintellect” and “Microsoft” as its friend assemblies.

 



using System;

using System.Runtime.CompilerServices; // For InternalsVisibleTo attribute

 



// This assembly's internal types can be accessed by any code written

// in the following two assemblies (regardless of version or culture): [assembly:InternalsVisibleTo("Wintellect, PublicKey=12345678...90abcdef")] [assembly:InternalsVisibleTo("Microsoft, PublicKey=b77a5c56...1934e089")]

 



internal sealed class SomeInternalType { ... } internal sealed class AnotherInternalType { ... }

 



Accessing the above assembly’s internal types from a friend assembly is trivial. For example, here’s how a friend assembly called “Wintellect” with a public key of “12345678...90abcdef” can access the internal type SomeInternalType in the preceding assembly.

 



using System;

 



internal sealed class Foo {

private static Object SomeMethod() {

// This "Wintellect" assembly accesses the other assembly's

// internal type as if it were a public type SomeInternalType sit = new SomeInternalType(); return sit;

}

}

 



Because the internal members of the types in an assembly become accessible to friend assem- blies, you should think carefully about what accessibility you specify for your type’s members and which assemblies you declare as your friends. Note that the C# compiler requires you to use the

/out:<file> compiler switch when compiling the friend assembly (the assembly that does not con- tain the InternalsVisibleTo attribute). The switch is required because the compiler needs to know the name of the assembly being compiled in order to determine if the resulting assembly should be


considered a friend assembly. You would think that the C# compiler could determine this on its own because it normally determines the output file name on its own; however, the compiler doesn’t decide on an output file name until it is finished compiling the code. So requiring the /out:<file> compiler switch improves the performance of compiling significantly.

Also, if you are compiling a module (as opposed to an assembly) using C#’s /t:module switch, and this module is going to become part of a friend assembly, you need to compile the module by using the C# compiler’s /moduleassemblyname:<string> switch as well. This tells the compiler what as- sembly the module will be a part of so the compiler can allow code in the module to access the other assembly’s internal types.

 



 




Date: 2016-03-03; view: 635


<== previous page | next page ==>
Nbsp;   The Different Kinds of Type Members | Nbsp;   Member Accessibility
doclecture.net - lectures - 2014-2024 year. Copyright infringement or personal data (0.012 sec.)