I'm learning C# but I'm having trouble with passing the data NameValueCollection from one class to another in my console application, I'm experienced in using java but from reading about passing by value and passing by reference has me stumped. My demo code below of the two classes is as follows, my helper class.
namespace ConsoleApplication3
{
class Helper
{
public void Dostuff()
{
string name = "valves";
int num = 5;
NameValueCollection collection = new NameValueCollection();
collection.Add("Sam", "Dot Net Perls");
collection.Add("Bill", "Microsoft");
}
public NameValueCollection GetCollection()
{
NameValueCollection coll2 = Dostuff.Collection();
return coll2;
}
}
}
And here is my program class
namespace ConsoleApplication3
{
class Program
{
public void Main(string[] args)
{
Helper h1 = new ConsoleApplication3.Helper();
NameValueCollection newcollection = h1.GetCollection();
RandomInbuiltMethod(newcollection);
}
}
}
I'm not handling the passing of the NameValueCollection data properly and I don't want to make the helper methods static, Is there a way to do this, I'm sure I'm over creating the complexity and using to much resources for the Helper class, can anyone show me how to solve this.
Probably you want to return the collection created in the DoStuff method of the Helper class
class Helper
{
private NameValueCollection Dostuff()
{
string name = "valves";
int num = 5;
NameValueCollection collection = new NameValueCollection();
collection.Add("Sam", "Dot Net Perls");
collection.Add("Bill", "Microsoft");
return collection;
}
public NameValueCollection GetCollection()
{
return Dostuff();
}
}
Now, your main method will retrieve the collection with the values added inside the DoStuff method
Related
The hardest problem I'm having is illustrating the problem. It runs, but it feels like there's a much cleaner way to achieve the same thing. Is there a way for a method in one class to communicate with another object, without having to create a reference to that object as a property in the class? For instance, here's a very simplified example. I'd like to create a shelter object that stores pets. As well, I have a class that wants to interact with the shelter, potentially adding a pet to the shelter's list of pets. Is this only achievable through referencing the shelter on the encounter object? This doesn't feel like it scales well when we need one object to interact with many others, or many objects to interact with this one.
using System;
using System.Collections.Generic;
class Program
{
static Shelter shelter;
static Encounter encounter;
static void Main(string[] args)
{
// this is what I'd like to avoid
encounter = new Encounter();
encounter.shelter = shelter;
}
}
class Pet
{
string name;
public Pet()
{
name = "DefaultDog";
}
}
class Shelter
{
public List<Pet> pets;
public void AddPet(Pet pet)
{
pets.Add(pet);
}
}
class Encounter
{
// this is what I'd like to avoid
public Shelter shelter;
public void CapturePet()
{
shelter.AddPet(new Pet());
}
}
Thoughts?
If you use delegates, you can achieve the results you want without having to add any class references in the Encounter class. Delegates provide you with the flexibility necessary to add pets to as many shelters as you wish, as well as any other kind of side effects. You can read more about them here https://learn.microsoft.com/en-us/dotnet/standard/events/
using System;
using System.Collections.Generic;
namespace SODelegate
{
class Program
{
static Shelter shelter = new();
static Shelter anotherShelter = new();
static Encounter encounter = new();
static void Main(string[] args)
{
encounter.OnCapturePet += delegate (object sender, EventArgs eventArgs)
{
Console.WriteLine("Running first delegate");
shelter.AddPet(new Pet());
};
encounter.OnCapturePet += delegate (object sender, EventArgs eventArgs)
{
Console.WriteLine("Running second delegate");
anotherShelter.AddPet(new Pet());
};
encounter.CapturePet();
}
}
class Pet
{
string name;
public Pet()
{
name = "DefaultDog";
}
}
class Shelter
{
public List<Pet> pets = new();
public void AddPet(Pet pet)
{
pets.Add(pet);
}
}
class Encounter
{
public event EventHandler OnCapturePet;
public void CapturePet()
{
Console.WriteLine("Running capture pet");
this.OnCapturePet(this, EventArgs.Empty);
}
}
}
Your code actually isn't valid as is-- you've got to create an instance of the Encounter class, which will typically look something like this:
encounter = new Encounter();
This is where you're supposed to initialize and create that encounter. And if an encounter isn't valid with a shelter, you have to provide it. In this case it is idiomatic to pass it as an argument to the constructor:
shelter = new Shelter();
encounter = new Encounter(shelter);
The constructor might look like this:
class Encounter
{
protected readonly Shelter _shelter;
public Encounter(Shelter shelter)
{
_shelter = shelter;
}
}
Now your encounter always knows what shelter it is associated with by accessing its own _shelter field.
To answer your question-- is there some way for your Shelter to automatically figure out what Encounter it goes with? The answer is no. This is because you can have more than one shelter.
var shelters = new List<Shelter>();
shelters.Add(new Shelter());
shelters.Add(new Shelter());
var encounter = new Encounter(); //Which shelter is this associated with?
You have to tell it which one:
var shelters = new List<Shelter>();
shelters.Add(new Shelter());
shelters.Add(new Shelter());
var encounter = new Encounter(shelters[0]);
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;
}
}
}
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);
}
I'm working on a simple cache class for my application.
using System;
namespace Program {
public class Cache {
public delegate int CacheMethodInt();
public static int Get(CacheMethodInt method) {
//todo: generate cachekey here
return method.Invoke();
}
}
public class Calculator {
public int Add(int x, int y) {
return x + y;
}
}
class Program {
static void Main(string[] args) {
Calculator c = new Calculator();
Console.WriteLine(Cache.Get(() => c.Add(1, 2)));
}
}
}
In Cache:Get I need to check whether the return value is already cached and if so return it without invoking the method. The problem is that I can't figure out how to generate a good cachekey. In this case I would like something like this:
Calculator:Add:1(int):2(int)
Is it possible to get this info in Cache:Get? I'm using .NET 2.0.
It's possible using reflection.
As alternative, on a project I used Postsharp for the same purposes. As benefit more generic and common approach
And do not forget about cache invalidation or expiration.
Related question shows how to get MethodInfo and method name:
Using MethodInfo.GetCurrentMethod() in anonymous methods
When you have MethodInfo than you can get all you need
I'm a brand-newbie to C#, albeit not programming, so please forgive me if I mix things up a bit -- it's entirely unintentional. I've written a fairly simple class called "API" that has several public properties (accessors/mutators). I've also written a testing console application that uses reflection to get an alphabetically list of names & types of each property in the class:
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using MyNamespace; // Contains the API class
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hi");
API api = new API(1234567890, "ABCDEFGHI");
Type type = api.GetType();
PropertyInfo[] props = type.GetProperties(BindingFlags.Public);
// Sort properties alphabetically by name.
Array.Sort(props, delegate(PropertyInfo p1, PropertyInfo p2) {
return p1.Name.CompareTo(p2.Name);
});
// Display a list of property names and types.
foreach (PropertyInfo propertyInfo in type.GetProperties())
{
Console.WriteLine("{0} [type = {1}]", propertyInfo.Name, propertyInfo.PropertyType);
}
}
}
}
Now what I need is a method that loops through the properties and concats all the values together into a querystring. The problem is that I'd like to make this a function of the API class itself (if possible). I'm wondering if static constructors have something to do with solving this problem, but I've only been working with C# for a few days, and haven't been able to figure it out.
Any suggestions, ideas and/or code samples would be greatly appreciated!
This is unrelated to static constructors. You can do it with static methods:
class API {
public static void PrintAPI() {
Type type = typeof(API); // You don't need to create any instances.
// rest of the code goes here.
}
}
You can call it with:
API.PrintAPI();
You don't use any instances when you call static methods.
Update: To cache the result, you can either do it on first call or in an static initializer:
class API {
private static List<string> apiCache;
static API() {
// fill `apiCache` with reflection stuff.
}
public static void PrintAPI() {
// just print stuff from `apiCache`.
}
}