Unable to call method using instance - c#

Why does the first way of calling method not work in following context? I am trying to use in another method of another class:
var center = Setting.CacheInstance.GetCentres(new Request
{
}); // this does not work
var center2= Setting.GetCentres(new Request
{
}); // this works
Class:
public sealed class Setting
{
private static Lazy<Setting> lazy =
new Lazy<Setting>(() => new Setting());
public static Setting CacheInstance
{
get
{
if (!lazy.IsValueCreated)
lazy = new Lazy<Setting>(() => new Setting());
return lazy.Value;
}
}
private Setting()
{
}
public static List<string> GetCentres(Request request)
{
return GetCentres(request);
}
private static List<string> GetCentres(Request request)
{
//implementation
}
}
What am I missing here?

GetCentres is static, so you can only call it from the class, not from an instance.
Setting.CacheInstance.GetCentres first gets the instance, and then tries to call the static on it. Remove the static on the method:
public List<string> GetCentres(Request request)
{
return GetCentres(request);
}

you can also check this article of jon skeet : http://csharpindepth.com/Articles/General/Singleton.aspx ..all different ways to implement single ton pattern which you are trying to implement
first way is not working because its static method
var center = Setting.CacheInstance.GetCentres(new Request
GetCentres is static method you cannot call it via isntace
solution - remvoe static make method accessible via instance, there is no extra check in your property getter
public sealed class Setting
{
private static Lazy<Setting> lazy =
new Lazy<Setting>(() => new Setting());
public static Setting CacheInstance
{
get
{
return lazy.Value;
}
}
private Setting()
{
}
public List<string> GetCentres(Request request)
{
return GetCentres(request);
}
//you cannot have two methos with same name and same parameter that
//is also issue
//private List<string> GetCentres(Request request)
//{
//implementation
//}
}

GetCentres is a static method, therefore you won't be able to invoke it using an instance of the class. You need to either invoke it by using the class itself (so Setting.GetCentres), or remove the static qualifier from the method. You have more information in the official C# Programming Guide.

In C#, static members cannot be accessed with instance.Static members belong to the class instead of a specific instance.It means that only one instance of a static field exists or you don't create any. It will be shared by all instances.
Setting.GetCentres()
Or
Remove the static modifier from GetCentres ()
public List<string> GetCentres(Request request)
{
return GetCentres(request);
}

Related

Locking and thread safe around streaming API

Probably a fairly simple question but I want to know the best practice in making the code thread safe.
I am using an external non thread-safe API within a mutli-threaded environment.
It returns an IEnumerable<ApiDto>.
I then map each of the ApiDto to our application's DTO: MyDto.
How do I ensure that the code is thread-safe?
For example:
This is my class that gets items from API
public class ApiRepo
{
private IApi api;
public ApiRepo()
{
api=new Api("url");
}
public IEnumerable<MyDto> GetItems()
{
var apiDtos = api.GetNonThreadSafeItems();
foreach(var apiDto in apiDtos)
{
var myDto = new MyDto(apiDto.Name);
yield return myDto;
}
}
}
This is my client application.
Multiple instances of Client are created and data is retrieved from the API.
public class Client
{
public void GetData()
{
var items = new ApiRepo().GetItems().ToList();
Console.WriteLine(items.Count);
}
}
Should I put a lock within Client.GetData() or is there any better way to make the code thread-safe?
An API is 'not thread safe' means it operate base on some golbal resource whitout synchronize mechanism. So, in order to get correct result form the API, your need to make sure only one thread call it at one time. Base on your sample, most easy way to do that is like
public class ApiRepo
{
static private object theLock = new object();
private IApi api;
public ApiRepo()
{
api=new Api("url");
}
public IEnumerable<MyDto> GetItems()
{
IEnumerable<ApiDto> apiDtos = null;
lock(theLock)
{
apiDtos = api.GetNonThreadSafeItems();
}
foreach(var apiDto in apiDtos)
{
var myDto = new MyDto(apiDto.Name);
yield return myDto;
}
}
}

Call Method based on Type of Parameter

I have an object that can be of type AudioRequest or VideoRequest. Both classes inherit from Request. I have this class:
public static DoThings
{
public static void HandleRequest(AudioRequest r)
{
// Do things.
}
public static void HandleRequest(VideoRequest r)
{
// Do things.
}
}
I want to be able to call DoThings.HandleRequest(r) where r can be either a VideoRequest or AudioRequest and have it call the correct one. Is that possible? I have no control over the *Request classes, so I can't do anything to them. I do have control of the DoThings class and the code that calls HandleRequest. This is the code that calls it, it is WebAPI:
public Response Post(Request input)
{
return DoThings.HandleRequest(input);
}
The code above gives the error Argument 1: cannot convert from 'Request' to 'AudioRequest'.
The original code that I was cleaning up had this:
if (input.GetType() == typeof(AudioRequest))
{
var audioRequest = (AudioRequest)input;
DoThings.HandleRequest(audioRequest);
}
else if (input.GetType() == typeof(VideoRequest))
{
var videoRequest = (VideoRequest)input;
DoThings.HandleRequest(videoRequest);
}
But I figured there was a cleaner way to do this.
Based on the information you've provided so far, your question appears to be a duplicate of How to call a function dynamically based on an object type. I agree with the answer, that the fact that you want to do this suggests you should rethink the design. But, you can use dynamic to accomplish what you want.
Here's a simple console program that demonstrates the basic idea:
class Program
{
static void Main(string[] args)
{
A b = new B(), c = new C();
M(b);
M(c);
}
static void M(A a)
{
WriteLine("M(A)");
M((dynamic)a);
}
static void M(B b)
{
WriteLine("M(B)");
}
static void M(C c)
{
WriteLine("M(C)");
}
}
class A { }
class B : A { }
class C : A { }
The output is:
M(A)
M(B)
M(A)
M(C)
As you can see, in each case the M(A) method is called first, and then the appropriate M(B) or M(C) overload is called from M(A).
In your own example, this could look something like this:
public static DoThings
{
public static void HandleRequest(Request r)
{
// Dynamic dispatch to actual method:
HandleRequest((dynamic)r);
}
public static void HandleRequest(AudioRequest r)
{
// Do things.
}
public static void HandleRequest(VideoRequest r)
{
// Do things.
}
}
Note that dynamic does incur a run-time cost, particularly the first time a method is called with a given run-time type. But depending on the frequency and complexity of these "requests", using dynamic could be the cleanest way out of the current situation.
C# will call the appropriate function that matches the arguments and their types.
That being said, both of your functions accept AudioRequest, I believe one of those should accept a VideoRequest.
public static DoThings
{
public static void HandleRequest(AudioRequest r)
{
// Do things.
}
public static void HandleRequest(VideoRequest r)
{
// Do things.
}
}
If for some reason you must have two different functions that take only AudioRequest you can differentiate between two function with an extra parameter
public static class DoThings
{
public static void HandleRequest(AudioRequest r)
{
// Do things.
}
public static void HandleRequest(AudioRequest r, bool UseAlternativeMethod)
{
// Do other things.
}
}
Simply having a second parameter will call the second method regardless of it's value.
This isn't a best practices solution as you'd rather discriminate between them by accurately renaming the method name to be accurate but in practice you don't always have a choice.

How can I create a set-once app-level action that isn't enforced via runtime exceptions or swallowing second-sets?

I'd like to be able to specify an Action<string> at the app level that my library could then use for progress reporting. ConfigurationManager.AppSettings only allows XmlSerializeables, and Actions are not that.
The motivation is that console apps might just write to the console, webapps perhaps to a trace, and forms perhaps to files or a particular field, the point is the app should be able to configure it imo.
My approach currently is to have in the library a LibSettings class that has a static settable Action<string>. That means anyone can set it elsewhere too, which poses potential for bugs.
At first I thought maybe a static constructor (with parameters) would do but it turns out you can't call static constructors explicitly and you certainly can't give them parameters.
Is there any way to achieve my goal of being able to specify the Feedback action once and only onc in some sort of custom app settings, and not throw a runtime exception on second setting, or swallow the second setting? That is essentially like a singleton property of my design when I design it. Thanks in advance.
Serializing and deserializing a delegate usually isn't a good idea, as it easily leads to pretty serious security concerns (see arbitrary code execution).
Instead I would recommend having a enum or similar serializable type that identifies a number of statically defined functions and convert between them. Something like this:
public enum FeedbackAction
{
Console,
Trace,
...
}
public static class FeedbackActions
{
public static void Console(string text) { ... }
public static void Trace(string text) { ... }
public static Action<string> GetAction(FeedbackAction action)
{
switch (action)
{
case FeedbackAction.Console:
return Console;
case FeedbackAction.Trace:
return Trace;
default:
throw new ArgumentException("Invalid feedback action.", nameof(action));
}
}
}
Now whenever you're trying to use the app setting, just call FeedbackActions.GetAction to convert between your enum values and the appropriate Action<string>.
For example:
public static class Feedback
{
public static Action<string> feedbackAction;
public static object syncLock = new object();
public static void ProvideFeedback(string text)
{
if (feedbackAction == null)
{
// synchronize to avoid duplicate calls
lock (syncLock)
{
if (feedbackAction == null)
{
var value = ConfigurationManager.AppSettings["FeedbackAction"];
feedbackAction = FeedbackActions.GetAction(value);
}
}
}
feedbackAction(text);
}
}
This way you can safely call Feedback.ProvideFeedback, and its behavior will be driven by the app/web.config file.
If you need to make a solution that's flexible enough to handle almost any feedback action, I'd strongly recommend reading up on inversion of control in general and the Managed Extensibility Framework (MEF) in particular. A full implementation would be a bit too complex to provide here, but in general it would look a bit like this:
public interface IFeedbackAction
{
void ProvideFeedback(string text);
}
public interface IFeedbackMetadata
{
string Name { get; }
}
[Export(typeof(IFeedbackAction)), ExportMetadata("Name", "Console")]
public interface ConsoleFeedbackAction : IFeedbackAction { ... }
[Export(typeof(IFeedbackAction)), ExportMetadata("Name", "Trace")]
public interface TraceFeedbackAction : IFeedbackAction { ... }
public static class Feedback
{
[ImportMany]
public IEnumerable<Lazy<IFeedbackAction, IFeedbackMetadata>> FeedbackActions { get; set; }
private IFeedbackAction feedbackAction;
public static void ProvideFeedback(string text)
{
if (feedbackAction == null)
{
// synchronize to avoid duplicate calls
lock (syncLock)
{
if (feedbackAction == null)
{
var value = ConfigurationManager.AppSettings["FeedbackAction"];
feedbackAction = GetFeedbackAction(value);
}
}
}
feedbackAction.ProvideFeedback(text);
}
private static IFeedbackAction GetFeedbackAction(string name)
{
return FeedbackActions
.First(l => l.Metadata.Name.Equals(name)).Value;
}
}
With this method, consumers would be able to provide their own implementation of IFeedbackAction, decorated with the appropriate [Export] and [ExportMetadata] attributes, and simply specify use of their custom actions in the app/web.config file.
Ok, let's see if I inderstood all right.
Let's suppose this is your config class:
public static class LibSettings
{
public static readonly Action<string> TheAction{ get; private set; }
static LibSettings()
{
var action = ConfigurationManager.AppSettings["libAction"];
switch(action)
{
case "console":
TheAction = ConsoleAction;
break;
case "web":
TheAction = WebAction;
break;
//And as many as you need...
}
}
private static void ConsoleAction(string Parameter)
{
//Whatever it does...
}
private static void WebAction(string Parameter)
{
//Whatever it does...
}
}
Is this what you meant? it will be only set once whenever you access any property of the class, it cannot be modified externally and will change the Action upon an AppSeting record.
Ok, let's go with another approach. Now we will have two classes a temporal holder where you will set the action you want and the current settings class.
public static class TemporalHolder
{
public static Action<string> HeldAction{ get; set; }
}
public static class LibSettings
{
public static readonly Action<string> TheAction;
static LibSettings()
{
TheAction = TemporalHolder.HeldAction;
}
public static void Init()
{
/*Just do nothing as we will use it to fire the constructor*/
}
}
And now, to use it, just seth the action to the temporal holder and call anithing static on LibSettings:
TemporalHolder.Action = (your function);
LibSettings.Init();
And voila! no errors on second settings, it cannot be changed on runtime and cannot be reasigned. are all the conditions met?

Static/Instance methods and extension questions

I'm new to C# and I began working on a project that needed a method added to a class in C#. I found myself re examining the differences between static and instance methods and I'm unable to explain the following in a sample project.
My Core object:
namespace ExtendingObjects
{
public class MyCoreObject
{
public String name;
public String returnName()
{
return name;
}
}
}
My attempt to extend the object:
namespace ExtendingObjects
{
public static class Extensions
{
public static void addName(this MyCoreObject mco, String str)
{
mco.name=str;
}
public static String getName(this MyCoreObject mco)
{
return "test";
}
}
}
Calling program:
namespace ExtendingObjects
{
class Program
{
static void Main(string[] args)
{
MyCoreObject co = new MyCoreObject();
co.addName("test");
//Static method seems to work with instance?
String n = co.returnName();
Console.WriteLine("The name is " + n);
Console.ReadLine();
//Does not work
//Static method from a type
//String n2 = MyCoreObject.getName()
}
}
}
It was my understanding that static items stayed with the class and instance items with the instance per MSDN Static and Instance Members. However, I seem to be able to access a static method through an instance above, but not able to access a static method through a type.
Why does co.returnName() work and not MyCoreObject.getName()? I would think they would be reverse based on my reading. How can I make the getName() method available without instantiating the object first?
Thanks in advance.
Your two methods are extension methods, which are meant to look like instance methods when they're called. They can be called statically, but you need to supply the instance as the first argument, and specify the class which declares the extension method, not the type that the method "extends":
Extensions.getName(co);
When you call an extension method "as" an instance method, it's just a compiler trick. So this code:
co.addName("test");
is compiled to the exact equivalent of:
Extensions.addName(co, "test");
(As an aside, you would do well to start following normal .NET naming conventions as soon as possible. The earlier you get in the habit, the better.)

Static variable initialization using new gives a code hazard

I am working on some code which is something like this:
class A
{
static SomeClass a = new Someclass("asfae");
}
Someclass contains the required constructor.
The code for this compiles fine without any warning. But I get a code hazard in system:
"The Someclass ctor has been called from static constructor and/or
static initialiser"
This code hazard part of system just to make it better by warning about possible flaws in the system or if system can get into bad state because of this.
I read somewhere on the web that static constructor/initialiser can get into deadlock in c# if they wait for a thread to finish. Does that have something to do with this?
I need to get rid of this warning how can i do this.
I can't make the member unstatic as it's used by a static function.
What should I do in this case , Need help.
You could hide it behind a property and initialize it on first use (not thread-safe);
class A
{
static SomeClass aField;
static SomeClass aProperty
{
get
{
if (aField == null) { aField = new Someclass("asfae"); }
return aField;
}
}
}
or use Lazy (thread-safe):
class A
{
static Lazy<SomeClass> a = new Lazy<SomeClass>(() => new Someclass("asfae"));
}
...or this very verbose thread safe version :)
class A
{
static SomeClass aField;
static object aFieldLock = new object();
static SomeClass aProperty
{
get
{
lock (aFieldLock)
{
if (aField == null) { aField = new Someclass("asfae"); }
return aField;
}
}
}
}
By initialising it as a static field, it behaves as it would in a static constructor, i.e. it probably gets initialised the first time an instance of your class is instantiated, but might happen earlier. If you want more control over exactly when the field is initialised, you could use Lazy<T>, e.g.:
{
static Lazy<SomeClass> a = new Lazy<SomeClass>(() => new Someclass("asfae"));
}
This way, you know that the initialisation of SomeClass will only happen the first time the field is accessed and its Value property called.
I think to understand your problem you need to know the difference between static constructors and type initializers, there is a great article from Jon Skeet about this issue:
http://csharpindepth.com/Articles/General/Beforefieldinit.aspx
The point is that following constructions are not the same, and there are difference in the behavior:
class Test
{
static object o = new object();
}
class Test
{
static object o;
static Test()
{
o = new object();
}
}
In any case, you could try to create a static constructor for your class to be able to have more control on this initialization, and maybe the warning will disappear.
If the member is only used by a static method, and only by this one, I would recommend you to put it in the scope if this static method and not as class member.

Categories

Resources