I am a bit confused on why isn't this code running through. This is only a small portion of the code, but everything works besides the part of the code where I try to:
return item.priceUsd and return "No Price Found", That I am trying to assign to a variable string coin_price
public class Exchange
{
public string exchangeId { get; set; }
public string baseId { get; set; }
public string quoteId { get; set; }
public string baseSymbol { get; set; }
public string quoteSymbol { get; set; }
public string volumeUsd24Hr { get; set; }
public string priceUsd { get; set; }
public string volumePercent { get; set; }
}
public class Exchanges
{
public List<Exchange> data { get; set; }
}
public static Exchanges GetPrice(string coin_name, string exchange_name)
{
using (HttpClient Client = new HttpClient())
{
string response = Client.GetStringAsync(base_URL + "assets/" + coin_name + "/markets").Result;
Exchanges list = JsonConvert.DeserializeObject<Exchanges>(response);
foreach(var item in list.data)
{
if(item.exchangeId == exchange_name)
{
return item.priceUsd;
}
}
return "No Price Found";
}
}
public class Program
{
static void Main(string[] args)
{
string coin_price = Method.GetPrice(name, ename);
//Console.WriteLine(coin_price);
Console.ReadLine();
}
}
I keep getting the " Cannot implicitly convert type " error. But I've made sure the type of "item.priceUsd" is a string and I am trying to return it and assign to another string "coin_price".
What am I missing here?
So, the main issue I see is that the method needs to return the class type Exchanges and you are returning a string
C# is type-safe, meaning that when you declare a new method and tell it that the return value is supposed to be a string, the method body needs to return a string.
so that is why it is returning the error Can't implicitly convert type.
Since you are returning strings, either way, try to change the methods return type to string.
Like this:
public static string GetPrice(string coin_name, string exchange_name){
//your code here.
}
If you want to return another type, you need to change the return values so that it returns the type the method needs.
Related
I need your help. I've got the following situation that I have a method with has to determine some conditions and depending on these conditions, returning an object of a specific type.
Now, I do not want to say public object methodXY() with object as return type but I have the approach which does not seem to work yet.
public T methodXY<T>()
{
if (condition A)
return (T)Convert.ChangeType(myValue, typeof(myType));
else if (condition B)
return (T)Convert.ChangeType(myValue, typeof(myOtherType));
else
throw new exception("xyz")
}
But with this, it seems that I have to set the return type already when calling the method. That's what I don't want and don't can.
//myType looks like this
public class myType
{
public string name;
public string firstname;
public string address;
}
and
//myOtherType looks like
public class myOtherType
{
public string name;
public string firstname;
}
Do you need more or more detailed information? Let me know.
Thanks in advance :-)
EDIT:
Here is the complete code sample of the method with object
public object myMethod(MyDto myDto)
{
userHasRoles = GetUserRoles();
if (userHasRoles .Contains("Admin"))
return (mapper.Map<myType>(myDto));
else if (userHasRoles.Contains("User"))
return (mapper.Map<myOtherType>(myDto));
throw new Exception("No elements!");
}
As far as I understand the problem, you need to return a more complete data when the retriever is the admin, and a not-so-complete one when not.
If that is the objective, then you can retrieve the appropriate data from the database and fill in an object of one of the following classes:
public class PersonData {
public string Name { get; private set; }
public string Surname { get; private set; }
}
public class ExtendedPersonData: PersonData {
public string Name { get; private set; }
public string Surname { get; private set; }
public string Address { get; private set; }
}
Since the latter class inherits from the former, you can just create a List<PersonData> and that will cover both cases.
Another, different approach: the data class takes into account the user in order to return or not certain data:
class Person {
public Person(User usr, string address)
{
this.User = usr;
this.address = address;
}
public string User { get; private set; }
public string Name { get; private set; }
public string Surname { get; private set; }
public string Address {
get {
string toret = "N/A";
if ( this.User.IsAdmin() ) {
toret = this.address;
}
return toret;
}
}
private string address;
}
Neither of both solutions is perfect, and both have their own issues, but the problem, at least how you stated it, cannot be solved.
Hope this helps.
I have a method as follows which gets data and stores them to specific variables. I also have two static variables that preserves their value if a condition is met. My question is how can I store this data in attributes in a specific class ?
Like for example, I have a class called UserDetails with attributes :
UserDetails class
public class UserDetails {
public static string RateCountry { get; set; }
public static string RateWeek { get; set; }
public int Start { get; set; }
public int Length { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
Second Class
For now, its working like this. But I want to enhance it by making use of objects.
public static string RateCountry { get; private set; }
public static string RateWeek { get; private set; }
public ActionResult ShowList()
{
int start = Convert.ToInt32(Request["start"]);
int length = Convert.ToInt32(Request["length"]);
string name = Request["search[value]"];
string address = Request[("columns[3][search][value]")];
string rateType = Request[("columns[7][search][value]")];
if (string.IsNullOrEmpty(rateType)) // if null, reset the static variables to null
{
RateCountry = "";
RateWeek = "";
}
else
{
if (CheckDate(rateType)) // if contains date, assign to RateWeek
{
RateWeek = rateType;
}
else
{
RateCountry = rateType; // else if contains a string word, assing to ratecountry
}
}
var items = AssignDetails(start, length, name, address, RateWeek, RateCountry);
return items;
}
Then instead of passing several parameters like start, length, name etc. in the method AssignDetails, I can pass an object of the UserDetails class directly taking into consideration the static variables.
Can someone please help ?
Note: In C#, they are called properties not attributes. Attributes are a totally different thing.
What you want to do is straight forward:
Firstly, you need to change your method so it accepts your class UserDetails as an argument:
public void AssignDetails(UserDetails userDetails)
{
// Use userDetails here to do whatever you want
}
Secondly, when you call the above method, you need to pass the argument to it. You can create an instance of UserDetails and pass it to the AssignDetails method:
var userDetails = new UserDetails
{
Start = start,
Length = length,
Name = name
Address = address
}
I am not sure why RateWeek, and RateCountry properties are static in your class, but to set those you can do them as below (Please note it is using the class and not the instance of the class):
UserDetails.RateWeek = RateWeek;
You could make use of the instance's properties as an indirection to the class' static properties, although all this thing is really ugly in terms of design.
public class UserDetails
{
public static string PersistedRateCountry { get; set; }
public static string PersistedRateWeek { get; set; }
public static string RateCountry
{
get { return string.IsNullOrEmpty(rateType) ? "" : PersistedRateCountry; }
set { PersistedRateCountry = value; }
}
public static string RateWeek
{
get { return string.IsNullOrEmpty(rateType) ? "" : PersistedRateWeek; }
set { PersistedRateWeek= value; }
}
public static string RateWeek { get; set; }
public int Start { get; set; }
public int Length { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
I strongly suggest you to move these static properties out to another class, which would be responsible for persisting them.
E.g. try to separate your Data Object (which just holds data) from your Business Object (which contains business logic, and is constructed by receiving a Data Object as parameter). Put all that crazy persistence logic in the Business Object, and use the Business Object everywhere in your code (instead of using the Data Object).
Keep your classes short and clean. If you are coding a lot in the same class, it's probably because you got a bad object-oriented design.
In my common.cs class I have the below declarations for a list based on a class:
public static List<edbService> edb_service;
public class edbService
{
public string ServiceID { get; set; }
public string ServiceName { get; set; }
public string ServiceDescr { get; set; }
public string ServiceInterval { get; set; }
public string ServiceStatus { get; set; }
public string ServiceUrl { get; set; }
public string SourceApplication { get; set; }
public string DestinationApplication { get; set; }
public string Function { get; set; }
public string Version { get; set; }
public string userid { get; set; }
public string credentials { get; set; }
public string orgid { get; set; }
public string orgunit { get; set; }
public string customerid { get; set; }
public string channel { get; set; }
public string ip { get; set; }
}
I have a public method to populate the list from xml data files declared like this in the same class (common.cs):
#region PublicMethods
public List<edbService> populateEDBService(string xmlDataFile)
{
try
{
XElement x = XElement.Load(global::EvryCardManagement.Properties.Settings.Default.DataPath + xmlDataFile);
// Get global settings
IEnumerable<XElement> services = from el in x.Descendants("Service")
select el;
if (services != null)
{
edb_service = new List<edbService>();
foreach (XElement srv in services)
{
edbService edbSrv = new edbService();
edbSrv.ServiceID = srv.Element("ServiceID").Value;
edbSrv.ServiceName = srv.Element("ServiceName").Value;
edbSrv.ServiceDescr = srv.Element("ServiceDescr").Value;
edbSrv.ServiceInterval = srv.Element("ServiceInterval").Value;
edbSrv.ServiceStatus = srv.Element("ServiceStatus").Value;
edbSrv.ServiceUrl = srv.Element("ServiceUrl").Value;
foreach (XElement ServiceHeader in srv.Elements("ServiceHeader"))
{
edbSrv.SourceApplication = ServiceHeader.Element("SourceApplication").Value;
edbSrv.DestinationApplication = ServiceHeader.Element("DestinationApplication").Value;
edbSrv.Function = ServiceHeader.Element("Function").Value;
edbSrv.Version = ServiceHeader.Element("Version").Value;
foreach (XElement ClientContext in ServiceHeader.Elements("ClientContext"))
{
edbSrv.userid = ClientContext.Element("userid").Value;
edbSrv.credentials = ClientContext.Element("credentials").Value;
edbSrv.orgid = ClientContext.Element("orgid").Value;
edbSrv.orgunit = ClientContext.Element("orgunit").Value;
edbSrv.customerid = ClientContext.Element("customerid").Value;
edbSrv.channel = ClientContext.Element("channel").Value;
edbSrv.ip = ClientContext.Element("ip").Value;
}
}
edb_service.Add(edbSrv);
}
}
}
catch (Exception ex)
{
/* Write to log */
Common.logBuilder("CustomerCreate : Form --> CustomerCreate <--", "Exception", Common.ActiveMQ,
ex.Message, "Exception");
/* Send email to support */
emailer.exceptionEmail(ex);
}
return edb_service;
}
but the problem is, in my calling class when I try to have a list returned from this method, it is not found - I get a compile error that an object reference is required.
I am trying to call it like this:
Common.edbService edb_service = Common.populateEDBService("CardUpdate.xml");
and I get the below error:
An object reference is required for the non-static field, method, or property 'EvryCardManagement.Common.populateEDBService(string)'
What am I doing wrong?
I would like to have a generic method that can be called from several classes (which run async after being instantiated by background workers on my form)
You can try making your method as static.
public static List<edbService> populateEDBService(string xmlDataFile)
{
//Your code here
....
}
Now you can call this method from all the other classes by using common.populateEDBService();
You need either to create the class static, or to create an object to call it.
class edbService { }
public static void Main() {
//this is error
edbService.populateEDBService("");
//this is correct
edbService s = new edbService();
s.populateEDBService("");
}
The last line in my example shows the object reference required by the compiler. The s variable here is the object reference.
Are there any missing values in your XML? The.Value property won't work if the value is missing. So if ServiceID is missing then srv.Element("ServiceID").Value; will cause an error. You can get it to return an empty string for missing values, for example, by instead using (string)srv.Element("ServiceID");
I created the following:
public class HttpException
{
public string Text { get; set; }
public string Message { get; set; }
public string InnerExceptionMessage { get; set; }
public string InnerExceptionInnerExceptionMessage { get; set; }
}
I'm calling the class like this:
var e = new HttpException() {
Text = "City not created",
Message = ex.Message,
InnerExceptionMessage = ex.InnerException.Message,
InnerExceptionInnerExceptionMessage = ex.InnerException.InnerException.Message
};
var jsonMsg = JSON.ToJSONString(e);
Is there a way I could make it so I can call the class with just the parameters of a text message and the exception and
then have it return a string jsonMsg
Note that the JSON.ToJSONString(e) is an external class that I am using to form a JSON string.
You mean you want a constructor like this?
public class HttpException
{
public string Text { get; private set; }
private readonly Exception ex;
public string Message { get { return this.ex.message; } }
public string InnerExceptionMessage { get { return this.ex.... } }
public string InnerExceptionInnerExceptionMessage { get { return this.ex....} }
public HttpException(string text, Exception ex)
{
this.Text = text;
this.Exception = ex;
}
}
I still wouldn't put the JSON code in there though, that's a separate concern and you don't normally want to mix serialization code with regular class code.
You can use the implicit operator to make implicit cast of the class like this:
public static void Main()
{
HttpException ex = new HttpException ();
string text = ex;
Console.WriteLine(text);
Console.ReadLine();
}
public class HttpException
{
public string Text = "goofy";
public static implicit operator string(HttpException ex)
{
return ex.Text;
}
}
Remarks:
The implicit operator doesn't stop to string you can make any cast you want.
You can use the explicit operator for doing explicit cast string test = (string)goofy; which might be somewhat more readable.
Cons of using implicit operator:
It's hardly discoverable (It's hard from someone different from yourself to find this "feature" and yourself can forgot about that if you take the code from a month from now.)
It's make the code more complex to read (someone might thing what the hell is going on here).
It's error prone.
As mentioned by zzzzBov, you can simply override the ToString() method.
However, if the only use for this object is to create the json string, I would consider creating the class like this:
public class HttpException
{
public string Text { get; set; }
public string Message { get; set; }
public string InnerExceptionMessage { get; set; }
public string InnerExceptionInnerExceptionMessage { get; set; }
public static string CreateJsonString(string Text, string Message,
string InnerExceptionMessage,
string InnerExceptionInnerExceptionMessage) {
return JSON.ToJSONString(new HttpException() {
Text = "City not created",
Message = ex.Message,
InnerExceptionMessage = ex.InnerException.Message,
InnerExceptionInnerExceptionMessage =
ex.InnerException.InnerException.Message});
}
}
then all you have to write in your code is:
var jsonMsg = HttpException.CreateJsonString("City not created",
ex.Message,
ex.InnerException.Message,
ex.InnerException.InnerException.Message
);
Implicit operators:
public static implicit operator string(HttpException exception)
{
return JSON.ToJSONString(e);
}
This implicitly converts an HttpException into a string behind the scenes, so now you can do this:
string json = new HttpException();
I have this issue where I'm sending a request for a JSON Feed. The issue is that the feed has a dynamic header (i.e. when I send a request for "testinput1" the header response will be testinput1.
Therefore I need to make my RootObject dynamic, but I'm not sure how, could you please help me?
I've entered the troublesome part of the code below
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
textBlock1.Text = "Details Loaded.";
short_description.Text = feed.testinput1.short_description; // can I make testinput1 a constant? its based on code below
});
public class Event
{
public string description { get; set; }
public string datetime { get; set; }
}
public class TrackCode
{
public string short_description { get; set; }
public List<Event> events { get; set; }
}
public class RootObject
{
public string tracker;
public TrackCode testinput1// This needs to be based on user input each time
{
get; // Can I do something here to make sure that the "testinput1" changes each time?
set; // And create a constant that can be referred to?
}
}
Hopefully I can do something like this:
short_description.Text = feed.trackcode.short_description; // this is a constant
public class RootObject
{
public string tracker = "AB123456789NZ"; // This is the variable that changes
public TrackCode trackcode // this becomes a constant
{
get { return tracker; } // uses tracking number as value for JSON when it retrieves it
set { tracker = value;}
}
}
Where have I gone wrong? Thankyou!