NullReferenceException
or incorrect behavior and output.VisitData
method, a VisitData
occurs, let's find out where null
comes from. Place the caret to use the dc
parameter in the VisitData
method and run the analysis ( R # -> Inspect -> Value Origin ):public class Main
{
void Start()
{
Console .WriteLine(Do( new DataClass()));
}
void Start2()
{
Console .WriteLine(Do( null ));
}
int Do(DataClass data)
{
var v = new Visitor();
return v.VisitData(data);
}
}
public class DataClass
{
public int GetData()
{
return 0;
}
}
public class Visitor
{
public int VisitData(DataClass dc)
{
return dc.GetData();
}
}
* This source code was highlighted with Source Code Highlighter .
dc
(just the place where the exception occurs)data
parameter to the VisitData
methodDo
method with “good data” (in the tree, the data of interest to us is highlighted by the bolt )Do
method with null
is the problem we are looking for.Main.Start
method can display. To do this, select the expression dataProvider.Foo
and call Value Origin on it:public interface IInterface
{
int Foo();
}
public class Base1 : IInterface
{
public virtual int Foo()
{
return 1;
}
}
public class Base2 : IInterface
{
private readonly int _foo = 2;
public Base2()
{
}
public Base2( int foo)
{
this ._foo = foo;
}
public virtual int Foo()
{
return _foo;
}
}
public class Main
{
public void Start(IInterface dataProvider)
{
Console .WriteLine(dataProvider.Foo());
}
public void Usage()
{
Start( new Base2(3));
}
}
* This source code was highlighted with Source Code Highlighter .
Foo
method, which returns a constant of 1
Foo
method, which returns the value of the _foo
field, as well as all sources of values for this field:3
2
i
inside Console.WriteLine
and run the Value Origin analysis:class Main
{
void Foo()
{
var list = new List < int >();
list.AddRange(GetData());
list.AddRange(GetDataLazy());
ModifyData(list);
foreach ( var i in list)
{
Console .WriteLine(i);
}
}
void ModifyData( List < int > list)
{
list.Add(6);
}
private IEnumerable < int > GetData()
{
return new [] { 1, 2, 3 };
}
IEnumerable < int > GetDataLazy()
{
yield return 4;
yield return 5;
}
}
* This source code was highlighted with Source Code Highlighter .
Add
method. Sumptuously!5
will go. Select it and call Value Destination:public class testMy
{
void Do()
{
int x = 5;
var list = Foo(x);
foreach ( var item in list)
{
Console .WriteLine(item);
}
}
List < int > Foo( int i)
{
var list = new List < int >();
list.Add(i);
return list;
}
}
* This source code was highlighted with Source Code Highlighter .
5
:Foo
methodpublic class MyClass
{
void Main()
{
var checkFunction = GetCheckFunction();
Console .WriteLine(checkFunction(1));
}
Func< int , bool > GetCheckFunction()
{
Func< int , bool > myLambda = x =>
{
Console .WriteLine(x);
return x > 100; //
};
return myLambda;
}
}
* This source code was highlighted with Source Code Highlighter .
x
are taken. Select its use in the Console.WriteLine
call and call Value Origin:1
, this is the desired value for x
x>100
, and call Value Destination ( R # -> Inspect -> Value Destination ):WriteLine
method, which uses the value returned by the lambda.Console.WriteLine
) with two lines:Func<Func< int , bool >, int , bool > invocator = (func, i) => func(i);
Console .WriteLine(invocator (checkFunction,1));
* This source code was highlighted with Source Code Highlighter .
x>100
falls. The code with nested lambdas is very difficult for an ordinary person to understand, which makes the analysis even more popular. Moreover, you can try to create a collection of nested lambdas - and it will work! But such exercises I will leave the reader and the difficult real life.Source: https://habr.com/ru/post/85693/
All Articles