- ${appsetting:item=mysetting:default=mydefault} - produces "mydefault" if no appsetting
-
-
- [Target("MyFirst")]
- public sealed class MyFirstTarget : AsyncTaskTarget
- {
- public MyFirstTarget()
- {
- this.Host = "localhost";
- }
-
- [RequiredParameter]
- public Layout Host { get; set; }
-
- protected override Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken token)
- {
- string logMessage = this.RenderLogEvent(this.Layout, logEvent);
- string hostName = this.RenderLogEvent(this.Host, logEvent);
- return SendTheMessageToRemoteHost(hostName, logMessage);
- }
-
- private async Task SendTheMessageToRemoteHost(string hostName, string message)
- {
- // To be implemented
- }
- }
-
- protected override Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken token)
- {
- return CustomWriteAsync(logEvent, token);
- }
-
- private async Task CustomWriteAsync(LogEventInfo logEvent, CancellationToken token)
- {
- await MyLogMethodAsync(logEvent, token).ConfigureAwait(false);
- }
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- | Condition | -Foreground Color | -Background Color | -
|---|---|---|
| level == LogLevel.Fatal | -Red | -NoChange | -
| level == LogLevel.Error | -Yellow | -NoChange | -
| level == LogLevel.Warn | -Magenta | -NoChange | -
| level == LogLevel.Info | -White | -NoChange | -
| level == LogLevel.Debug | -Gray | -NoChange | -
| level == LogLevel.Trace | -DarkGray | -NoChange | -
- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${basedir}/${level}.log
- All - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- - Mail target works best when used with BufferingWrapper target - which lets you send multiple log messages in single mail -
-- To set up the buffered mail target in the configuration file, - use the following syntax: -
-
- - To set up the buffered mail target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- - To print the results, use any application that's able to receive messages over - TCP or UDP. NetCat is - a simple but very powerful command-line tool that can be used for that. This image - demonstrates the NetCat tool receiving log messages from Network target. -
-
- - There are two specialized versions of the Network target: Chainsaw - and NLogViewer which write to instances of Chainsaw log4j viewer - or NLogViewer application respectively. -
-${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
-
- [Target("MyFirst")]
- public sealed class MyFirstTarget : TargetWithContext
- {
- public MyFirstTarget()
- {
- this.Host = "localhost";
- }
-
- [RequiredParameter]
- public Layout Host { get; set; }
-
- protected override void Write(LogEventInfo logEvent)
- {
- string logMessage = this.RenderLogEvent(this.Layout, logEvent);
- string hostName = this.RenderLogEvent(this.Host, logEvent);
- return SendTheMessageToRemoteHost(hostName, logMessage);
- }
-
- private void SendTheMessageToRemoteHost(string hostName, string message)
- {
- // To be implemented
- }
- }
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
-
- <system.net>
- <defaultProxy enabled = "true" useDefaultCredentials = "true" >
- <proxy usesystemdefault = "True" />
- </defaultProxy>
- </system.net>
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- The example web service that works with this example is shown below
-
- - Asynchronous target wrapper allows the logger code to execute more quickly, by queuing - messages and processing them in a separate thread. You should wrap targets - that spend a non-trivial amount of time in their Write() method with asynchronous - target to speed up logging. -
-- Because asynchronous logging is quite a common scenario, NLog supports a - shorthand notation for wrapping all targets with AsyncWrapper. Just add async="true" to - the <targets/> element in the configuration file. -
-
-
- ... your targets go here ...
-
- ]]>
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- This example causes the messages to be written to server1, - and if it fails, messages go to server2.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- This example causes the messages not contains the string '1' to be ignored.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- - This example works like this. If there are no Warn,Error or Fatal messages in the buffer - only Info messages are written to the file, but if there are any warnings or errors, - the output includes detailed trace (levels >= Debug). You can plug in a different type - of buffering wrapper (such as ASPNetBufferingWrapper) to achieve different - functionality. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- This example causes the messages to be written to either file1.txt or file2.txt - chosen randomly on a per-message basis. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- This example causes each log message to be repeated 3 times.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- This example causes each write attempt to be repeated 3 times, - sleeping 1 second between attempts if first one fails.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- This example causes the messages to be written to either file1.txt or file2.txt. - Each odd message is written to file2.txt, each even message goes to file1.txt. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- This example causes the messages to be written to both file1.txt or file2.txt -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
-
- [CanBeNull] object Test() => null;
-
- void UseTest() {
- var p = Test();
- var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
- }
-
- [NotNull] object Foo() {
- return null; // Warning: Possible 'null' assignment
- }
-
- public void Foo([ItemNotNull]List<string> books)
- {
- foreach (var book in books) {
- if (book != null) // Warning: Expression is always true
- Console.WriteLine(book.ToUpper());
- }
- }
-
- public void Foo([ItemCanBeNull]List<string> books)
- {
- foreach (var book in books)
- {
- // Warning: Possible 'System.NullReferenceException'
- Console.WriteLine(book.ToUpper());
- }
- }
-
- [StringFormatMethod("message")]
- void ShowError(string message, params object[] args) { /* do something */ }
-
- void Foo() {
- ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
- }
-
- void LogInfo([StructuredMessageTemplate]string message, params object[] args) { /* do something */ }
-
- void Foo() {
- LogInfo("User created: {username}"); // Warning: Non-existing argument in format string
- }
-
- namespace TestNamespace
- {
- public class Constants
- {
- public static int INT_CONST = 1;
- public const string STRING_CONST = "1";
- }
-
- public class Class1
- {
- [ValueProvider("TestNamespace.Constants")] public int myField;
- public void Foo([ValueProvider("TestNamespace.Constants")] string str) { }
-
- public void Test()
- {
- Foo(/*try completion here*/);//
- myField = /*try completion here*/
- }
- }
- }
-
- void Foo([ValueRange(0, 100)] int value) {
- if (value == -1) { // Warning: Expression is always 'false'
- ...
- }
- }
-
- void Foo([NonNegativeValue] int value) {
- if (value == -1) { // Warning: Expression is always 'false'
- ...
- }
- }
-
- void Foo(string param) {
- if (param == null)
- throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
- }
-
- public class Foo : INotifyPropertyChanged {
- public event PropertyChangedEventHandler PropertyChanged;
-
- [NotifyPropertyChangedInvocator]
- protected virtual void NotifyChanged(string propertyName) { ... }
-
- string _name;
-
- public string Name {
- get { return _name; }
- set { _name = value; NotifyChanged("LastName"); /* Warning */ }
- }
- }
-
- Examples of generated notifications:
- Function Definition Table syntax:
-
- [ContractAnnotation("=> halt")]
- public void TerminationMethod()
-
- [ContractAnnotation("null <= param:null")] // reverse condition syntax
- public string GetName(string surname)
-
- [ContractAnnotation("s:null => true")]
- public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
-
- // A method that returns null if the parameter is null,
- // and not null if the parameter is not null
- [ContractAnnotation("null => null; notnull => notnull")]
- public object Transform(object data)
-
- [ContractAnnotation("=> true, result: notnull; => false, result: null")]
- public bool TryParse(string s, out Person result)
-
- [LocalizationRequiredAttribute(true)]
- class Foo {
- string str = "my string"; // Warning: Localizable string
- }
-
- [CannotApplyEqualityOperator]
- class NoEquality { }
-
- class UsesNoEquality {
- void Test() {
- var ca1 = new NoEquality();
- var ca2 = new NoEquality();
- if (ca1 != null) { // OK
- bool condition = ca1 == ca2; // Warning
- }
- }
- }
-
- [BaseTypeRequired(typeof(IComponent)] // Specify requirement
- class ComponentAttribute : Attribute { }
-
- [Component] // ComponentAttribute requires implementing IComponent interface
- class MyComponent : IComponent { }
-
- [UsedImplicitly]
- public class TypeConverter {}
-
- public class SummaryData
- {
- [UsedImplicitly(ImplicitUseKindFlags.InstantiatedWithFixedConstructorSignature)]
- public SummaryData() {}
- }
-
- [UsedImplicitly(ImplicitUseTargetFlags.WithInheritors | ImplicitUseTargetFlags.Default)]
- public interface IService {}
-
- [Pure] int Multiply(int x, int y) => x * y;
-
- void M() {
- Multiply(123, 42); // Warning: Return value of pure method is not used
- }
- [MustUseReturnValue("Use the return value to...")].
-
- class Foo {
- [ProvidesContext] IBarService _barService = ...;
-
- void ProcessNode(INode node) {
- DoSomething(node, node.GetGlobalServices().Bar);
- // ^ Warning: use value of '_barService' field
- }
- }
-
- [SourceTemplate]
- public static void forEach<T>(this IEnumerable<T> xs) {
- foreach (var x in xs) {
- //$ $END$
- }
- }
-
-
- [SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")]
- public static void forEach<T>(this IEnumerable<T> collection) {
- foreach (var item in collection) {
- //$ $END$
- }
- }
-
- Applying the attribute on a template method parameter:
-
- [SourceTemplate]
- public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) {
- /*$ var $x$Id = "$newguid$" + x.ToString();
- x.DoSomething($x$Id); */
- }
-
-
- public class MyStringCollection : List<string>
- {
- [CollectionAccess(CollectionAccessType.Read)]
- public string GetFirstString()
- {
- return this.ElementAt(0);
- }
- }
- class Test
- {
- public void Foo()
- {
- // Warning: Contents of the collection is never updated
- var col = new MyStringCollection();
- string x = col.GetFirstString();
- }
- }
-
- static void ThrowIfNull<T>([NoEnumeration] T v, string n) where T : class
- {
- // custom check for null but no enumeration
- }
-
- void Foo(IEnumerable<string> values)
- {
- ThrowIfNull(values, nameof(values));
- var x = values.ToList(); // No warnings about multiple enumeration
- }
-
- void Foo([LanguageInjection(InjectedLanguage.CSS, Prefix = "body{", Suffix = "}")] string cssProps)
- {
- // cssProps should only contains a list of CSS properties
- }
-
- ${appsetting:item=mysetting:default=mydefault} - produces "mydefault" if no appsetting
-
-
- [Target("MyFirst")]
- public sealed class MyFirstTarget : AsyncTaskTarget
- {
- public MyFirstTarget()
- {
- this.Host = "localhost";
- }
-
- [RequiredParameter]
- public Layout Host { get; set; }
-
- protected override Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken token)
- {
- string logMessage = this.RenderLogEvent(this.Layout, logEvent);
- string hostName = this.RenderLogEvent(this.Host, logEvent);
- return SendTheMessageToRemoteHost(hostName, logMessage);
- }
-
- private async Task SendTheMessageToRemoteHost(string hostName, string message)
- {
- // To be implemented
- }
- }
-
- protected override Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken token)
- {
- return CustomWriteAsync(logEvent, token);
- }
-
- private async Task CustomWriteAsync(LogEventInfo logEvent, CancellationToken token)
- {
- await MyLogMethodAsync(logEvent, token).ConfigureAwait(false);
- }
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- | Condition | -Foreground Color | -Background Color | -
|---|---|---|
| level == LogLevel.Fatal | -Red | -NoChange | -
| level == LogLevel.Error | -Yellow | -NoChange | -
| level == LogLevel.Warn | -Magenta | -NoChange | -
| level == LogLevel.Info | -White | -NoChange | -
| level == LogLevel.Debug | -Gray | -NoChange | -
| level == LogLevel.Trace | -DarkGray | -NoChange | -
- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${basedir}/${level}.log
- All - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- - Mail target works best when used with BufferingWrapper target - which lets you send multiple log messages in single mail -
-- To set up the buffered mail target in the configuration file, - use the following syntax: -
-
- - To set up the buffered mail target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- - To print the results, use any application that's able to receive messages over - TCP or UDP. NetCat is - a simple but very powerful command-line tool that can be used for that. This image - demonstrates the NetCat tool receiving log messages from Network target. -
-
- - There are two specialized versions of the Network target: Chainsaw - and NLogViewer which write to instances of Chainsaw log4j viewer - or NLogViewer application respectively. -
-${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
-
- [Target("MyFirst")]
- public sealed class MyFirstTarget : TargetWithContext
- {
- public MyFirstTarget()
- {
- this.Host = "localhost";
- }
-
- [RequiredParameter]
- public Layout Host { get; set; }
-
- protected override void Write(LogEventInfo logEvent)
- {
- string logMessage = this.RenderLogEvent(this.Layout, logEvent);
- string hostName = this.RenderLogEvent(this.Host, logEvent);
- return SendTheMessageToRemoteHost(hostName, logMessage);
- }
-
- private void SendTheMessageToRemoteHost(string hostName, string message)
- {
- // To be implemented
- }
- }
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
- ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}
-
- <system.net>
- <defaultProxy enabled = "true" useDefaultCredentials = "true" >
- <proxy usesystemdefault = "True" />
- </defaultProxy>
- </system.net>
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- The example web service that works with this example is shown below
-
- - Asynchronous target wrapper allows the logger code to execute more quickly, by queuing - messages and processing them in a separate thread. You should wrap targets - that spend a non-trivial amount of time in their Write() method with asynchronous - target to speed up logging. -
-- Because asynchronous logging is quite a common scenario, NLog supports a - shorthand notation for wrapping all targets with AsyncWrapper. Just add async="true" to - the <targets/> element in the configuration file. -
-
-
- ... your targets go here ...
-
- ]]>
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- This example causes the messages to be written to server1, - and if it fails, messages go to server2.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- This example causes the messages not contains the string '1' to be ignored.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- - This example works like this. If there are no Warn,Error or Fatal messages in the buffer - only Info messages are written to the file, but if there are any warnings or errors, - the output includes detailed trace (levels >= Debug). You can plug in a different type - of buffering wrapper (such as ASPNetBufferingWrapper) to achieve different - functionality. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- This example causes the messages to be written to either file1.txt or file2.txt - chosen randomly on a per-message basis. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- This example causes each log message to be repeated 3 times.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- This example causes each write attempt to be repeated 3 times, - sleeping 1 second between attempts if first one fails.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- This example causes the messages to be written to either file1.txt or file2.txt. - Each odd message is written to file2.txt, each even message goes to file1.txt. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
- This example causes the messages to be written to both file1.txt or file2.txt -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - To set up the log target programmatically use code like this: -
-
-
- [CanBeNull] object Test() => null;
-
- void UseTest() {
- var p = Test();
- var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
- }
-
- [NotNull] object Foo() {
- return null; // Warning: Possible 'null' assignment
- }
-
- public void Foo([ItemNotNull]List<string> books)
- {
- foreach (var book in books) {
- if (book != null) // Warning: Expression is always true
- Console.WriteLine(book.ToUpper());
- }
- }
-
- public void Foo([ItemCanBeNull]List<string> books)
- {
- foreach (var book in books)
- {
- // Warning: Possible 'System.NullReferenceException'
- Console.WriteLine(book.ToUpper());
- }
- }
-
- [StringFormatMethod("message")]
- void ShowError(string message, params object[] args) { /* do something */ }
-
- void Foo() {
- ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
- }
-
- void LogInfo([StructuredMessageTemplate]string message, params object[] args) { /* do something */ }
-
- void Foo() {
- LogInfo("User created: {username}"); // Warning: Non-existing argument in format string
- }
-
- namespace TestNamespace
- {
- public class Constants
- {
- public static int INT_CONST = 1;
- public const string STRING_CONST = "1";
- }
-
- public class Class1
- {
- [ValueProvider("TestNamespace.Constants")] public int myField;
- public void Foo([ValueProvider("TestNamespace.Constants")] string str) { }
-
- public void Test()
- {
- Foo(/*try completion here*/);//
- myField = /*try completion here*/
- }
- }
- }
-
- void Foo([ValueRange(0, 100)] int value) {
- if (value == -1) { // Warning: Expression is always 'false'
- ...
- }
- }
-
- void Foo([NonNegativeValue] int value) {
- if (value == -1) { // Warning: Expression is always 'false'
- ...
- }
- }
-
- void Foo(string param) {
- if (param == null)
- throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
- }
-
- public class Foo : INotifyPropertyChanged {
- public event PropertyChangedEventHandler PropertyChanged;
-
- [NotifyPropertyChangedInvocator]
- protected virtual void NotifyChanged(string propertyName) { ... }
-
- string _name;
-
- public string Name {
- get { return _name; }
- set { _name = value; NotifyChanged("LastName"); /* Warning */ }
- }
- }
-
- Examples of generated notifications:
- Function Definition Table syntax:
-
- [ContractAnnotation("=> halt")]
- public void TerminationMethod()
-
- [ContractAnnotation("null <= param:null")] // reverse condition syntax
- public string GetName(string surname)
-
- [ContractAnnotation("s:null => true")]
- public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
-
- // A method that returns null if the parameter is null,
- // and not null if the parameter is not null
- [ContractAnnotation("null => null; notnull => notnull")]
- public object Transform(object data)
-
- [ContractAnnotation("=> true, result: notnull; => false, result: null")]
- public bool TryParse(string s, out Person result)
-
- [LocalizationRequiredAttribute(true)]
- class Foo {
- string str = "my string"; // Warning: Localizable string
- }
-
- [CannotApplyEqualityOperator]
- class NoEquality { }
-
- class UsesNoEquality {
- void Test() {
- var ca1 = new NoEquality();
- var ca2 = new NoEquality();
- if (ca1 != null) { // OK
- bool condition = ca1 == ca2; // Warning
- }
- }
- }
-
- [BaseTypeRequired(typeof(IComponent)] // Specify requirement
- class ComponentAttribute : Attribute { }
-
- [Component] // ComponentAttribute requires implementing IComponent interface
- class MyComponent : IComponent { }
-
- [UsedImplicitly]
- public class TypeConverter {}
-
- public class SummaryData
- {
- [UsedImplicitly(ImplicitUseKindFlags.InstantiatedWithFixedConstructorSignature)]
- public SummaryData() {}
- }
-
- [UsedImplicitly(ImplicitUseTargetFlags.WithInheritors | ImplicitUseTargetFlags.Default)]
- public interface IService {}
-
- [Pure] int Multiply(int x, int y) => x * y;
-
- void M() {
- Multiply(123, 42); // Warning: Return value of pure method is not used
- }
- [MustUseReturnValue("Use the return value to...")].
-
- class Foo {
- [ProvidesContext] IBarService _barService = ...;
-
- void ProcessNode(INode node) {
- DoSomething(node, node.GetGlobalServices().Bar);
- // ^ Warning: use value of '_barService' field
- }
- }
-
- [SourceTemplate]
- public static void forEach<T>(this IEnumerable<T> xs) {
- foreach (var x in xs) {
- //$ $END$
- }
- }
-
-
- [SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")]
- public static void forEach<T>(this IEnumerable<T> collection) {
- foreach (var item in collection) {
- //$ $END$
- }
- }
-
- Applying the attribute on a template method parameter:
-
- [SourceTemplate]
- public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) {
- /*$ var $x$Id = "$newguid$" + x.ToString();
- x.DoSomething($x$Id); */
- }
-
-
- public class MyStringCollection : List<string>
- {
- [CollectionAccess(CollectionAccessType.Read)]
- public string GetFirstString()
- {
- return this.ElementAt(0);
- }
- }
- class Test
- {
- public void Foo()
- {
- // Warning: Contents of the collection is never updated
- var col = new MyStringCollection();
- string x = col.GetFirstString();
- }
- }
-
- static void ThrowIfNull<T>([NoEnumeration] T v, string n) where T : class
- {
- // custom check for null but no enumeration
- }
-
- void Foo(IEnumerable<string> values)
- {
- ThrowIfNull(values, nameof(values));
- var x = values.ToList(); // No warnings about multiple enumeration
- }
-
- void Foo([LanguageInjection(InjectedLanguage.CSS, Prefix = "body{", Suffix = "}")] string cssProps)
- {
- // cssProps should only contains a list of CSS properties
- }
-