Visual Studio said my variables are useless in a private method [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have simple scenario where I started to repeat same code multiple times, so I decided to move it in a private method, depending on a if/else it's being edited and my variables that are listed below might overwrite it's value which is perfectly fine:
ProductResponse identificationResults = new ProductResponse(); // I understand this assignment gets overridden in private method below but that is goal
long? productIdentificationRecordId = null; // I understand this assignment gets overridden in private method below but that is goal
I'm invoking my method on a few places in a code that's reason why I created private method to avoid code repetition in same file:
await SetProductStatusAndPerformDbActions(productCompany, userId );
private async Task SetProductStatusAndPerformDbActions(Company productCompany, long userId, ProductType productType, ProductStatus status, long? productIdentificationRecordId, ProductResponse identificationResults, CancellationToken cancellationToken)
{
status = GetCompanyProductStatus(productCompany.Id, identificationResults);
productIdentificationRecordId = await PerformDbAction(status, productType, userId, cancellationToken); // underlined this code
identificationResults = await IdentifyCompanyProduct(productCompany, cancellationToken); // underlined this code
}
Visual Studio says 'Remove this useless assignment to a local variable
productIdentificationRecordId'
Visual Studio says 'Remove this useless assignment to a local variable
identificationResults'
I understand this assignments gets overridden in private method below but that is point of private method because I want to use for example productIdentificationRecordId and its new value right after I call this private method because goal of private method is to modify it and that is it..
I'm not using vars which might cause this warning so I don't know what to do here.
How this could be written to avoid this scenarios ?
Edit:
Added screenshot from the private method, variables are grayed as they are not used:

Because these parameters are not being passed by reference, setting them to any value will only change the value of the parameter variables local to your helper method: it will not impact the values that were passed in to those parameters.
Since you don't use the new values you're assigning to those parameters inside the method, Visual Studio is smart enough to recognize that setting values to them has no effect. It's warning you about that, which is good because in this case you might think your code is doing something that it's not really doing.

Related

C# action invoke is changing `this` [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 18 hours ago.
Improve this question
TL;DR
If a C# Action referencing a class method still has a reference to the original Target, then why is this being changed when I invoke the Action and set breakpoints in that method?
More Context
I have the following setup in a .NET project:
// MyClass.cs
public class MyClass
{
private float _someValue = -1f;
private int _instanceId = 12345;
public void Method()
{
Updater.Instance.RegisterUpdate(_instanceId, doStuff);
}
private void doStuff(float deltaTime)
{
// Do stuff with _someValue
}
}
// Updater.cs
public class Updater
{
public static Updater Instance = new();
private readonly List<Action<float>> _updateActions = new();
public void RegisterUpdate(int instanceId, Action<float> updateAction)
{
// Validation...
_updateActions.Add(updateAction);
}
public void Update()
{
foreach (Action<float> action in _updateActions)
action.Invoke(Time.deltaTime);
}
}
Essentially, Updater wraps a list of registered Actions, and invokes them all when Update is called.
In Visual Studio, I can set breakpoints in MyClass.doStuff(), and they are getting hit when Updater.Update() is called. Unfortunately, while paused on a breakpoint, I get no value when I hover over the value of _someValue, nor is the field even mentioned in the Locals Window, and when I enter _someValue in the Immediate Window, I get "The identifier _someValue is not in the scope". In addition, the this value in the Locals Window is of type Updater, not MyClass.
And yet, everything is working fine. The conditional logic inside doStuff that works with _someValue is still working as expected when I step through, I just can't inspect the values as I step, which makes things difficult to debug. Also, when I go up the call stack to Updater.Update and inspect the current element of _updateActions, I can see that its Target property is correctly set to the instance of MyClass. So what is happening here? Trying to figure out what this is feels like JavaScript crap lol, not C#.
Turns out the issue was something in my actual code that was not captured in the minimum working example in my question. That is, in my real code, doStuff was a local function inside of Method. If doStuff is a separate method, as in my question, then this is of the correct MyClass type. Strangely, I can only repro the this-changing behavior of local functions in Unity components, not in vanilla C# classes, so this may be a result of the Mono compiler that Unity uses on the backend.
Anyway, thank you to the commenters for helping me get here. Hopefully this helps someone in the future.

How reuse a instance of a object for all functions requests? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I am working on a azure function that makes dependency injection of a object, and I would like to know what I can do to it's create the instance just once in the constructor (when I deploy the function to production) and at the others requests to the functions reuse the first instance created.
I made a injection dependency of the object that I want to reuse but it don't worked.
There is no "function scope" variable in C# like there is in Native C++. But there is a bunch of similar constructs you can use:
Make a property with Public get but private Set. That way only class code (like the constructor) can set values. You see this pattern used abundantly all over the .NET Framework. However it does not really avoid setting the value in class code by accident. It works best if you never use this value anywhere else in classcode.
Another option is the "readonly" variable attribute. It enforces that the value must be set once (in the Constructor), but can also only be set once. You would still have to hand in the instance to the constructor or use static.
Another option is to add a static variable to store the data. But that is a pattern that is absolutely not adviseable. If you never need a second set of these instances with a different shared value, you have lost. And this will happen, as sure as the Garbage Collection. We got literal decades worth of experience of static values backfiring. So you really should stay with instance variables.
Another way is to add a Factory method. Often they are used if the instances need setup you can not leave to the average programmer using your code. You could even slightly breakt the pattern by having both a public constructor and a instance Factory Method. If you use the factory method, the shared thing is copied over from them Instance it is called on. If you use the Public constructor, a new shared thing is created.
The way to reuse a resource among multiple instances of the function is to declare it as static. For example, let's say I want to reuse an HttpClient:
public static class PeriodicHealthCheckFunction
{
private static HttpClient _httpClient = new HttpClient();
[FunctionName("PeriodicHealthCheckFunction")]
public static async Task Run(
[TimerTrigger("0 */5 * * * *")]TimerInfo healthCheckTimer,
ILogger log)
{
string status = await _httpClient.GetStringAsync("https://localhost:5001/healthcheck");
log.LogInformation($"Health check performed at: {DateTime.UtcNow} | Status: {status}");
}
}

Property or get method with cached result [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have a method that takes around 200ms to run and would therefor like to cache the result. This result will be used frequently, but it never changes.
I'm not entirely sure what the best solution would be for this, should I put this to a property or a get method?
As an example:
1
private string _result;
public string Result => _result ?? (_result = GetSlowResult());
2
private string _result;
public string GetResult() => _result ?? (_result = GetSlowResult());
Personally, from a property I typically expect it to be available "now" rather than "later" but with a Get method I expect the result to always retrieve a fresh GetSlowResult rather than using a cached value. I could change the method name to GetCachedResult but I'm not sold on that either as then it would seem you need to have called a GetResult method first.
Are there any guidelines to this? What do you prefer?
I would recommend you to use the Lazy<T> class. It causes you to pass a factory that talks about how to create that object, and after that, it is created only the first time you ask for it, and then uses the same reference(cached value).
Here's how it would look:
Lazy<T> Result = new Lazy<T>(GetSlowResult); //T is your type
Then, to use the result, just get her property Value:
T myResult = Result.Value;
You can see more about this in the official dotnet docs.
I would do this with read-only property and a method that fills the property.
If you know that result will be needed, you can load it at the begining - during startup of a service, activation ov view etc.
I mostly use ReactiveUI in WPF apps, so it would look like that:
// ViewModel constructor
GetResult = ReactiveCommand.CreateFromTask(async () => _model.GetResultAsync()); // notice that method is async
// there is also overload with CancelationToken
_result = GetResult.Retry(3).ToProperty(this, x => x.Result); // we can retry few times and we get change notification
GetResult.Subscribe(result =>{
// do something as soon as the result is loaded
});
GetResult.ThrownExceptions.Subscribe( errorHandler);
// ViewModel properties
private ObservableAsProperetyHelper<ResultType> _result;
public ResultType Result => _result.Value;
// view constructor
this.WhenActivated(d =>{ // d is CompositeDisposable for cleanup
ViewModel.GetResult.Execute().Subscribe().DisposeWith(d); // cancel command if the view is deactivated before it's finished
});
That way you can make async call in proper moment and store the result for later. You can also easily refresh the result - that becomes dirty when using lazy properties alone.
On another plus side, you can easily create loading spinner:
_isBusy = GetResult.IsExecuting.ToProperty(this, x => x.IsBusy);
I followed this pattern in a always-on windows service running custom HTTP server in the background. You can await GetResult.Execute() if you want to enforce loading at a particular moment.
In my practice, this pattern shows very little shortcomings - main one is boilerplate code, but with proper tools it can be written really fast.
If you are creating some service type app, console or whatever, MVVM pattern is still very usefull, you just don't do views.

How to use keyword `var` and Class in C# [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I want to start new browser Chrome process.
In the class ChromeDriver have a method to do this.
And tried to initialize ChromeDriver like this:
ChromeDriver browser;
private void OpenBrowser()
{
browser = new ChromeDriver(Browsers.Chrome);
}
Problem is:
I start n process browser Chrome, and it runs only one browser, another process not run my code(although it initialized).
So, I tried to change code:
private void OpenBrowser()
{
var browser = new ChromeDriver(Browsers.Chrome);
}
It's working, but another method was using the browser. But I can't declare var browser out of a method.
It will return error like:
The contextual keyword 'var' may only appear within a local variable declaration or in script code
Updated:
I saw all answer and know var is ChromeDriver in my situation.
But when to run it, have the problem.
I will describe more information.
Suppose, I need to start 2 Chrome process. After initialized two Chrome process, I will go to URL with:
browser.GoToUrl(link);
So, I will know it working or not working.
At first, the case using ChromeDriver it still opens 2 Chrome process, but it was only working with the second process, the first process not working.
At second, the case using var keyword, it opens 2 Chrome process, and it was also working with two processes.
I'm not 100% clear on what you are trying to do but I can answer the question as asked:
var is just syntactic sugar to save having to write the full name of the type. As you can see from the error it can only be used with local variables.
What this means is that the following two lines are equivalent:
ChromeDriver browser = new ChromeDriver(Browsers.Chrome);
var browser = new ChromeDriver(Browsers.Chrome);
When compiled the compiler will see that browser is being set to an object of type ChromeDriver and thus act as if it was declared as ChromeDriver.
The main advantage of this is when working with ugly long variable names (often with generics) such as:
Dictionary<string, Dictionary<int, List<double>> myObject = new Dictionary<string, Dictionary<int, List<double>>();
This could be written more readably as:
var myObject = new Dictionary<string, Dictionary<int, List<double>>();
As an additional note it may be implicit in what I've said but to be explicit you need to have an assignment to use var. You couldn't for example do:
var myObject;
Because the compiler would complain that it can't work out the type of myObject (which is pretty obvious looking at that line of code!).
How about to return your reference from method?
private ChromeDriver OpenBrowser()
{
return new ChromeDriver(Browsers.Chrome);
}
Also, according to example ChromeDriver class implements IWebDriver interface so it's better to write like this:
private IWebDriver OpenChromeBrowser()
{
return new ChromeDriver(Browsers.Chrome);
}
In your another method (in same class, couse your method is private) you can use it like this:
var driver = OpenChromeBrowser();
When you declare a var variable .net needs to know what kind of var you are declaring, so you can use var when you have on the other side the type of var you are declaring.
var cool = new MySuperBrowserClass();
var lol = 69;
In both cases .net knows that on the other side there is a class of type MySuperBrowserClass or just an int.
In other words: if you want to declare a var, no matter the context, you have to clarify its type.
Perhaps (maybe is not the case because of other reasons!) you can change in your first code sample where you have:
ChromeBrowser browser;
doing something like:
var browser = new ChromeDriver(Browsers.Chrome);
var is a keyword that can only be used within the scope of a method. Using it within the scope of a class will throw an error.
If you could use it outside a method the result would be the same as your first example, as all it does is infer the type, which would mean it'd be the same as declaring it as ChromeDriver.

C# - internal static readonly is null on access [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have the following code:
internal class FakeInvitationsRepository : InvitationsRepository
{
internal readonly static Dictionary<Guid, InvitationDbEntity> Data = new Dictionary<Guid, InvitationDbEntity>()
{
{ ...
Here's a screen-shot, for what its worth:
It's just some in-memory fake data, 3 items in all. The class lives inside an ASP.NET WebAPI project, not in a test DLL but in the WebAPI DLL for the time being.
An API call comes in and hits a breakpoint in the controller action where it tries to consume this fake data directly, no IoC yet or anything clever.
But the field Data is null. It's causing a null ref exception at runtime.
The C# language spec says:
If a static constructor (Section 10.11) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.
What's happening here such that the field is not initialized prior to first-use?
Note: A colleague has quickly sanity checked and is also bemused. Data is only ever set, never nulled by my code (its readonly afterall).
Edit
Here's the callstack of just my code:
System.Diagnostics.StackTrace t = new System.Diagnostics.StackTrace();
{ at Company.Product.WebAPI.Controllers.RenamedController.<GetInvitations>d__14.MoveNext()
at Company.Product.WebAPI.Controllers.RenamedController.GetInvitations(Guid id)
at lambda_method(Closure , Object , Object[] )
at Company.WebAPI.Product.Areas.RouteDebugger.InspectActionInvoker.InvokeActionAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
at Company.WebAPI.Product.Areas.RouteDebugger.InspectHandler.<>n__FabricatedMethod12(HttpRequestMessage , CancellationToken )
at Company.WebAPI.Product.Areas.RouteDebugger.InspectHandler.<SendAsync>d__e.MoveNext()
at Company.WebAPI.Product.Areas.RouteDebugger.InspectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
}
FrameCount: 84
frames: {System.Diagnostics.StackFrame[87]}
m_iMethodsToSkip: 3
m_iNumOfFrames: 84
Answer
I can't answer because the question was put on hold. Debatable.
Thanks to MStodd. The answer is silly and straight-forward, but somewhat surprising; I don't recall having ever seen this in 11 years of .NET programming.
The Data field was not yet initialized.
Placing a breakpoint in the initializer, the entire block goes red, showed that it was called on the next step.
The NullReferenceException was a red-herring and due to this.Invitations being null.
Of course, I was expecting the field to be initialized by the time that line is stopped at, I just didn't expect it to happen so late, and so assumed the null was causing my runtime exception.
There you go.
From your call stack i can deduce that the Invitations property is evaluated(in the Select body). Being the last one on the call stack i can deduce that the null reference raises due to the fact that Invitations is NULL!). I suppose that Data = NULL is NOT related to the call stack at all! but rather it is a debugger issue.

Categories