I am working on a trading API (activex from interactive brokers)which has a method called:
void reqMktDataEx(int tickerId, IContract contract, string generalDetails, int snapshot)
The issue is around the last parameter "int snapshot" which obviously requires an int input which actually indicates that whether trader wanna snapshot market data or not. So I guess that if I set it to non-zero, then the implicit conversion would convert this non-zero to be bool value "true".
However, I am using c# to connect to this api. Everything was fine until this one. I tried this:
A. void reqMktDataEx(1, AUDUSD, "100", 0)
Please ignore the first three parameters "1, AUDUSD, "100"", the only matter is the last one 0 as int. I got paused during debugging and the information is :
"Specified cast is not valid. Invalidcastexception is unhandled" and "when casting from a number, the number must not be infinity".
After this I learned that here is a difficulty for c# to treat 1 as bool true and 0 as bool false IMPLICITLY according this
web http://www.dotnetperls.com/convert-bool-int
B. I tried this
void reqMktDataEx(1, AUDUSD, "100", Convert.ToInt16(false)) I got similar error again.
C. I tried again this one:
void reqMktDataEx(1, AUDUSD, "100", int.Parse("false"))
the complaint is input string was not in a correct format. Make sure that you method arguments are in the right format.
MY GUESS:
Here is a inside configuration of C# which does not treat 0 as false and 1 as true. Is there any way to solve?
First Edit
As suspected by one professional programmer below, I post the contract class and audusd definition here for him.
namespace InteractiveBrokersTradingSystem
{
class Contract:TWSLib.IContract
{
public int conId { get; set; }
public string symbol { get; set; }
public string secType { get; set; }
public string expiry { get; set; }
public double strike { get; set; }
public string right { get; set; }
public string multiplier { get; set; }
public string exchange { get; set; }
public string primaryExchange { get; set; }
public string currency { get; set; }
public string localSymbol { get; set; }
public int includeExpired { get; set; }
public object comboLegs { get; set; }
public object underComp { get; set; }
public string comboLegsDescrip { get; set; }
public string secIdType { get; set; }
public string secId { get; set; }
}
}
namespace InteractiveBrokersTradingSystem
{
class Forex:Contract
{
public Forex(string preCurrency,string baseCurrency)
{
//conId = 14433401;
symbol = preCurrency;
secType = "CASH";
exchange = "IDEALPRO";
currency = baseCurrency;
strike = 0;
includeExpired = 0;
primaryExchange = "IDEALPRO";
}
}
}
The method I use to call the reqMktDataEx:
implementation first, simple inheritance:
public void MyReqMarketData(int tickId, IContract contract, string tickTypes, int snapshot)
{
reqMktDataEx(tickId, contract, tickTypes, snapshot);
}
private void AudButtonItemItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
Forex audusd = new Forex("AUD", "USD");
_myTwsClass.MyReqMarketData(1,audusd, "100", 0);
}
Second Edit:
System.InvalidCastException was unhandled
Message=Unable to cast object of type 'InteractiveBrokersTradingSystem.Forex' to type 'TWSLib.IContract'.
Source=InteractiveBrokersTradingSystem
It seems that here is some casting problem between the forex class I defined and the Icontract com thing. Here is my new definition:
namespace InteractiveBrokersTradingSystem
{
class Forex
{
public int conId { get; set; }
public string symbol { get; set; }
public string secType { get; set; }
public string expiry { get; set; }
public double strike { get; set; }
public string right { get; set; }
public string multiplier { get; set; }
public string exchange { get; set; }
public string primaryExchange { get; set; }
public string currency { get; set; }
public string localSymbol { get; set; }
public int includeExpired { get; set; }
public object comboLegs { get; set; }
public object underComp { get; set; }
public string comboLegsDescrip { get;set; }
public string secIdType { get; set; }
public string secId { get; set; }
public Forex(string preCurrency,string baseCurrency)
{
//conId = 0;
//symbol = preCurrency;
//secType = "CASH";
//expiry = null;
//strike = double.Parse("0");
//right = null;
//multiplier = null;
//exchange = "IDEALPRO";
//primaryExchange = "IDEALPRO";
//currency = baseCurrency;
//localSymbol = null;
//includeExpired = 0;
//comboLegs = null;
//underComp = null;
//comboLegsDescrip = null;
//secType = null;
//secId = null;
}
}
}
As you can see that the Forex class inherits from the TWS.IContract. how it could not be cast to Icontract successively?
There is no implicit conversion of a bool to an int. Only an explicit one:
Convert.ToInt32(someBool)
// or...
someBool ? 1 : 0
From that site you linked:
First, you cannot implicitly convert from bool to int. The C# compiler uses this rule to enforce program correctness. It is the same rule that mandates you cannot test an integer in an if statement.
Edit
int doesn't have a concept of infinity. Only float and double do. This means it won't be related to that parameter, unless that parameter just controls the flow of the code that is actually crashing. Which still means it isn't the conversion causing the problem.
You're getting a different error for int.Parse("false") because it is expecting a number, not a true/false value. This will always throw an exception at runtime, but it will throw in your code, not in the library's code.
I'm starting to think it is the second parameter, contract, for which you've supplied AUDUSD.
One more way is to have extension method:
public static class BooleanExtensions
{
public static int ToInt(this bool value)
{
return value ? 1 : 0;
}
}
then it can be used:
bool result = false;
result.ToInt();
make field tinyint in database
tinyint fieldname;
c# code
convert.toint32(fieldname.tostring());//returns 1 or 0
to get boolean value
covert.tobool(fieldname.tostring()) ;
There's no implicit cast to int from bool. So make your own. Then add them up.
Boolean
byFinancialCenter = false,
byProvider = false,
byServiceSite = false,
byProcedure = false;
int b2i(bool source) => source ? 1 : 0;
int ForeignKeyCount() => b2i(byFinancialCenter) + b2i(byProvider) + b2i(byServiceSite) + b2i(byProcedure);
The b2i is generic, as I needed the specific count in several places, including the last function makes it easy to use. Also, for maintenance, having the embedded function just under the bools makes it more likely that subsequent developers will see what's happening.
Related
I hope this isn't a foolishly simple question. Im very simply trying to figure out how to manipulate a relatively simple table in SQLite through C#.
Im looking to take a parameter and search a List of Arrays for one such array where the parameter matches, and return a related variable within that same array.
For example where an array in the list might be.
Name IATA
Brisbane BNE
The sqlbind:
public static List<Airport> LoadAirports()
{
using (IDbConnection cnn = new SQLiteConnection(LoadConnectionString()))
{
var output = cnn.Query<Airport>("select * from Airport", new DynamicParameters());
return output.ToList();
}
}
The Class:
class Airport
{
int Id { get; set; }
string Name { get; set; }
string LocationName { get; set; }
string IATA { get; set; }
string PortType { get; set; }
string PortOwner { get; set; }
string MotherPort { get; set; }
bool Active { get; set; }
bool IsApplyMeetAndGreet { get; set; }
decimal MeetAndGreet { get; set; }
}
The main Program:
List<Airport> Airports = new List<Airport>();
public FreightCalculator()
{
LoadAirportsList();
string OriginName = OriginInput.Value;
var OriginAirport = Airports.Where(s => s.Name == OriginName);
}
private void LoadAirportsList()
{
Airports = SqliteDataAccess.LoadAirports();
}
Ive tried various combinations of Where, Equals, For each indexing etc. Always getting an error of some kind.
The Error with the above Airports.Where is that the s.Name is inaccessible due to its protection level.
If I do:
var OriginAirport = Airports.Where(Name => Name == OriginName);
I get an error where the operand == cannot be used with Airport and String (Though Name is a string in Airport.)
Im either missing something simple or making this more complicated than it needs to be. Once I find the matching Airport, I need to return the IATA code.
Which I envisage looking like this:
var OriginIATA = OriginAirport.IATA;
Im tired and feeling dumb. Please help :(
Since you declared all members of the Airport class as properties I assume you wanted to expose them publicly.
The error you get is because they are private members and can't be accessed outside the class.
Change "Airport" class to:
class Airport
{
public int Id { get; set; }
public string Name { get; set; }
public string LocationName { get; set; }
public string IATA { get; set; }
public string PortType { get; set; }
public string PortOwner { get; set; }
public string MotherPort { get; set; }
public bool Active { get; set; }
public bool IsApplyMeetAndGreet { get; set; }
public decimal MeetAndGreet { get; set; }
}
I am trying to make a class in C# that can be used to return data of any types.
public class ResponseObject
{
public <T> data { get;set }
public Boolean Success { get; set; }
public string Message { get; set; }
}
The Object will be a wrapper for the response object when my application sends a request to the API.
i have tried researching this but cannot find any tutorials which are relevant to what i am trying to do.
Is this possible in C#? the Response Object will be converted to a JSON string and then sent as a response.
I will not be doing any processing of this object as that will already by done. I just want to place the data inside the ResponseObject and send it
I want to do something along the lines of:
var customers = repository.GetCustomers();
var orders = repository.GetOrders();
if(customers)
{
success = true;
message = "";
}
else{
success = false;
message = "failed to get customers";
}
if(orders)
{
orderssuccess = true;
ordersmessage = "";
}
else{
orderssuccess = false;
ordersmessage = "failed to get orders";
}
ResponseObject customerResponse = new ResponseObject{
data = customers,
success = success,
message = message
};
ResponseObject orderResponse = new ResponseObject{
data = orders,
success = orderssuccess,
message = ordersmessage
};
You need to add <T> to the class and use T as the type of your property.
public class ResponseObject<T>
{
public T data { get; set; }
public Boolean Success { get; set; }
public string Message { get; set; }
}
You have almost done it already! Just change your <T> to T.
public class ResponseObject<T> where T : class
{
public T data { get; set; }
public Boolean Success { get; set; }
public string Message { get; set; }
}
Here where T : class ensure that the generic type parameter is a reference type. From your question it seems you are going to pass in an object there.
You have two options here:
Make the class generic, or
Use generic methods for accessing the property
Here are the examples of both approaches:
// Make the class generic
public class ResponseObject<T> {
public T Data { get; set }
public Boolean Success { get; set; }
public string Message { get; set; }
}
// Use generic methods to access the property
public class ResponseObject {
private object data;
public T GetData<T>() {
return (T)data;
}
public void SetData<T>(T newData) {
data = newData;
}
public Boolean Success { get; set; }
public string Message { get; set; }
}
Second approach is less robust than the first one - basically, it's a glorified unrestricted cast. First approach, however, does not let you build a container of ResponseObjects with different Ts. You can address this problem by adding an interface on top of ResponseObject:
interface IResponseObject {
object DataObj { get; set }
Type ObjType { get; }
bool Success { get; set; }
string Message { get; set; }
}
public class ResponseObject<T> {
public T Data { get; set }
public ObjType => typeof(T);
public DataObj {
get => Data;
set => Data = value; // C# 7 syntax
}
public Boolean Success { get; set; }
public string Message { get; set; }
}
I have created a generic method, and I want to pass an object by a reference to this method to populate few properties. It compiles, and runs without problems, but the object is not being populated.
my generic method
public static void SplitAddress<T>(ref T ob, string addressToSplit) where T : Address
{
//ptr : Postcode, Town, Region
var ptr = addressToSplit.Split(new char[] { '-' }, 2, StringSplitOptions.RemoveEmptyEntries).ToList();
var pt = ptr[0].Split(new char[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries).ToList();
if (ptr.Count == 2)
{
ob.Region = ptr[1];
}
for (int x = 0; x < pt.Count; x++)
{
switch (x)
{
case 0:
{
ob.PostCode = pt[x];
break;
}
case 1:
{
ob.Town = pt[x];
break;
}
}
}
}
Object i want to pass
class Merchant : Address
{
public int MeId { get; set; }
public int HoId { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
public string PostCode { get; set; }
public string Town { get; set; }
public string Region { get; set; }
public string VatNr { get; set; }
public string TRSshopId { get; set; }
}
Address class
abstract class Address
{
public string PostCode;
public string Town { get; set; }
public string Region { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Adrress { get; set; }
}
method invocation
Methods.SplitAddress<Merchant>(ref me, row.Cells[i].Text);
I could create two overloaded methods, for two different object types, but they will repeat the same code, which I want to avoid.
It look very odd, but for example "Postcode" is being populated, but when I hover the mouse on "ob", the property is still empty.
EDIT
As #Lee astutely noticed, you are hiding the properties of Address in Member. Since your generic method is constrained to members of type Address, your code is actually changing the properties of the Address class that are hidden, not the properties of the Merchant class, so you are not seeing those changes if you have a variable of type Merchant. You would see the values if you cast the Member to an Address. Just remove those properties from Merchant and you should be fine.
p.s. Member inheriting form Address seems wrong - a member has an address, it is not an address. a better design would be:
class Merchant
{
public int MeId { get; set; }
public int HoId { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
public string VatNr { get; set; }
public string TRSshopId { get; set; }
}
Original Answer
I want to pass an object by a reference to this method to populate few properties
Since Address is a class, you don't need to use ref. A parameter of a reference types will contain a reference to the same object as the variable that's passed in, so you can change the values of the properties of that object and the calling method will see the changes. The main thing ref lets you do is change the reference to a different object, which you aren't doing, so using ref won't change what you are trying to do.
I suggest you run it in the debugger to make sure your if blocks are getting executed the way you expect them to. (e.g. is ptr.Count == 2 true? could it be greater then 2?)
Also your entire for block can be reduced to:
if(pt.Count > 0) ob.PostCode = pt[0];
if(pt.Count > 1) ob.Town = pt[1];
I have this code:
public IfStatement? m_IfStatement;
public struct IfStatement
{
public string Statement { get; private set; }
public string Comparison { get; private set; }
public string ConditionValue { get; private set; }
public string IfCondition_True { get; private set; }
public string IfCondition_False { get; private set; }
}
and when I'm trying to set values to the struct like this:
m_IfStatement = new IfStatement();
m_IfStatement.Statement = cboIfStatement.SelectedItem.ToString();
m_IfStatement.Comparison = cboComparison.SelectedItem.ToString();
m_IfStatement.ConditionValue = txtIfValue.Text;
m_IfStatement.IfTrue = "";
m_IfStatement.IfFalse = "";
I'm getting this error by the compailer:
'System.Nullable<Core.BaseControls.IntegrationTool.frmDataManipulation.IfStatement>'
does not contain a definition for 'Statement' and no extension method 'Statement'
accepting a first argument of type
'System.Nullable<Core.BaseControls.IntegrationTool.frmDataManipulation.IfStatement>'
could be found (are you missing a using directive or an assembly reference?)
What does it mean ? and how do I solve this...? please.
Both statements are in the same scope (e.g. in the same class).
Nullable types access with Value property. Nullable Types
public IfStatement? m_IfStatement;
public struct IfStatement
{
public string Statement { get; set; }
public string Comparison { get; set; }
public string ConditionValue { get; set; }
public string IfCondition_True { get; set; }
public string IfCondition_False { get; set; }
}
m_IfStatement = new IfStatement();
IfStatement ifStat = m_IfStatement.Value;
ifStat.Statement = cboIfStatement.SelectedItem.ToString();
ifStat.Comparison = cboComparison.SelectedItem.ToString();
ifStat.ConditionValue = txtIfValue.Text;
ifStat.TrueCondition = "";
ifStat.FalseCondition = "";
Since structs are value-types (and therefore cannot be null) and you want it be nullable, you should create a constructor to set the properties. This way you can keep your properties with private setters.
public struct IfStatement {
public IfStatement (string statement, string comparison, string conditionValue, string ifCondition_True, string ifCondition_False) {
Statement = statement;
Comparison = comparison;
ConditionValue = conditionValue;
IfCondition_True = ifCondition_True;
IfCondition_False = ifCondition_False;
}
public string Statement { get; private set; }
public string Comparison { get; private set; }
public string ConditionValue { get; private set; }
public string IfCondition_True { get; private set; }
public string IfCondition_False { get; private set; }
}
And use it like
m_IfStatement = new IfStatement(
cboIfStatement.SelectedItem.ToString(),
cboComparison.SelectedItem.ToString()
txtIfValue.Text,
"",
""
);
This will prevent any trouble you have setting a property of a nullable struct.
In your first section you have this:
public string Statement { get; private set; }
and your second
m_IfStatement.Statement = cboIfStatement.SelectedItem.ToString();
The second section you are setting Statement, which you have defined in your first that you can only do within the struct itself (i.e. marking it as private).
To fix this, simply change your definition(s) to read:
public string Statement { get; set; }
Background
I am working on a trading ActiveX API in visual studio 2010 on C#. Since it is an ActiveX API, I simply added the ActiveX as my reference. The api provides three group of things: Method you could use to call API, the Event with which the API updates information for you and some socalled ActiveX COM object.
ISSUE
I asked a related question here: C# boolean int conversion issue Finally, after viewing the exception has been thrown, I know that it is about casting. Here is the description of exception:
*System.InvalidCastException was unhandled Message=Unable to cast object of type
InteractiveBrokersTradingSystem.Forex' to type 'TWSLib.IContract'.
*
And here is my definition for Forex Class:
namespace InteractiveBrokersTradingSystem
{
class Forex:TWSLib.IContract
{
public int conId { get; set; }
public string symbol { get; set; }
public string secType { get; set; }
public string expiry { get; set; }
public double strike { get; set; }
public string right { get; set; }
public string multiplier { get; set; }
public string exchange { get; set; }
public string primaryExchange { get; set; }
public string currency { get; set; }
public string localSymbol { get; set; }
public int includeExpired { get; set; }
public object comboLegs { get; set; }
public object underComp { get; set; }
public string comboLegsDescrip { get;set; }
public string secIdType { get; set; }
public string secId { get; set; }
public Forex(string preCurrency,string baseCurrency)
{
//conId = 0;
//symbol = preCurrency;
//secType = "CASH";
//expiry = null;
//strike = double.Parse("0");
//right = null;
//multiplier = null;
//exchange = "IDEALPRO";
//primaryExchange = "IDEALPRO";
//currency = baseCurrency;
//localSymbol = null;
//includeExpired = 0;
// comboLegs = null;
//underComp = null;
//comboLegsDescrip = null;
//secType = null;
//secId = null;
}
}
}
You could see that I did not assign any value to the properties of the class and the exception is always the same no matter what kind of value I assign or not assign or null.
In the description of the api below as image we can see that some property with () like strike() as doulble and some not with () like secType as string; someone told me that it might be problem. Please, give me any hint related to this COM casting issue:
(source: minus.com)
(source: minus.com)
(source: minus.com)
Can you post some code that actually fails?
I think what's happening is that you're trying to cast a COM object to a plain .NET type and that will not work because the COM object needs to explicitly be mapped to a .NET type either by the Runtime Callable Wrapper or by manual mapping.
One suggestion I would have is to skip explicit casting and use the dynamic type in .NET 4.0 to access the properties of your COM object, then map it to whatever properties/objects you need it to. That way you'll be able to see exactly which part of the object doesn't want to map.