If you want your component to be CLS-compliant, you must use only CLS features in the following places:
However, it doesn't matter what features you use in the definitions of your private classes, in the definitions of private methods on public classes, and in local variables. Also, in the code that implements your class, you can use any language features you want and still have a CLS-compliant component.
Many language compilers targeting the runtime have agreed to support the data types and features in the CLS. These language compilers simplify CLS-compliance by making the CLS data types and features available to you so that you can create components using them. Language compilers that are able to produce CLS-compliant components are called CLS-compliant producer tools. Some language compilers can understand all of the CLS types and features, but do not support them to the extent of allowing you to create components that use those features. These language compilers or tools, which can consume CLS-compliant components but cannot produce them, are called CLS-compliant consumer tools.
When you design CLS-compliant components, it is helpful to use a language compiler that has the ability to produce CLS-compliant components. In some cases, these language compilers will assist you by providing a "switch" that you can throw to tell the compiler that you want your code to be CLS-compliant; the compiler will let you know when your code uses functionality that is not supported by the CLS. You could write CLS-compliant components without using a CLS-compliant language compiler, but it will probably be more difficult for two reasons: 1) you must keep track of CLS features yourself and make sure that you use only those features and follow CLS rules; 2) the compiler might not offer all the CLS features you would like to use.