Is it possible to change cast of an object dynamically? - c#

I want have a "pointer" to an object but the object can be one of two classes.
QuickFix.Message newOrderSingle;
if (ecn.versionFIX.Equals(VersionFIX.FSS_FIX44))
{
newOrderSingle = new QuickFix.FIX44.NewOrderSingle(
new ClOrdID(masterForm.OrderBook.GetNewClOrdIDBroker(ecn.brokerCode)),
new Symbol(symbol),
new Side(side),
new TransactTime(DateTime.Now),
ordType = new OrdType(OrdType.LIMIT));
}
else
{
newOrderSingle = new QuickFix.FIX42.NewOrderSingle(
new ClOrdID(masterForm.OrderBook.GetNewClOrdIDBroker(ecn.brokerCode)),
new HandlInst('1'),
new Symbol(symbol),
new Side(side),
new TransactTime(DateTime.Now),
ordType = new OrdType(OrdType.LIMIT));
}
Then later I want to do this, where "set" is a method of QuickFix.FIX44.NewOrderSingle:
newOrderSingle.Set(new Price(limitPrice));
Instead I have to do:
((QuickFix.FIX44.NewOrderSingle) newOrderSingle).Set(new Price(limitPrice));
Which is hard to read.
Can I change "cast" of NewOrderSingle dynamically in some way?

You have some options:
dynamic
You can use dynamic keyword to make "duck typing":
dynamic order= newOrderSingle;
order.Set(new Price(limitPrice));
Unfortunately, you loose intellisense and will get RuntimeBinderException when order has not such a method (is of type FIX42 f.e.).
GenericInvoker
You can use my library:
newOrderSingle.DetermineType()
.When((QuickFix.FIX42 msg) => msg.Set(/* ... */))
.Resolve();
Unfortunately, you need to hardcode type.
To sum up
If you need to use such approach, your classes are badly designed. Consider creating base / abstract class or some inteface:
interface IMessageSetable
{
Set(Price p);
}
public class FIX44 : IMessageSetable
{
// impl
}
then:
if (newOrderSingle is IMessageSetable)
((IMessageSetable)newOrderSingle).Set(price);

if you have access to the source code of QuickFix.Message, you can add it. perhaps you can add the set function to a common interface.
the really dirty way is using reflection. the code would look like this:
newOrderSingle.GetType().GetMethod("Set").Invoke(newOrderSingle, new Price(limitPrice)));
(I guess it will not compile directly, the function parameters needs to be adjusted)
you could also try to use the dynamic datatype

As long as you use the common base class QuickFix.Message you cannot use specific members without casting.
If you have a piece of code where you work with a specific subclass you can do:
if(newOrderSingle is QuickFix.FIX44.NewOrderSingle)
{
QuickFix.FIX44.NewOrderSingle ord44 = (QuickFix.FIX44.NewOrderSingle)newOrderSingle;
// from here on you can work with ord44:
ord44.Set(new Price(limitPrice));
// more code which uses ord44
}

Related

How do you store these generic parameters?

I am working with ServiceStack. This library has a method for dependency injection, called Register.
public IRegistration<TService> Register<TService>(TService> instance)
Which you call like this:
Container.Register<IFirstServiceInterface>(new FirstServiceInterfaceImplementation());
Container.Register<ISecondServiceInterface>(new SecondServiceInterfaceImplementation());
Now, I want to create a method which takes the same parameters as Register. In my method however, I would add the passed instance and interface type to an ICollection object, to pass it to ServiceStack's Register method at a later point in time. At the time I want to pass these parameters to ServiceStack, I would simply call:
foreach(var item in dependencyCollection)
{
ServiceStack.Register(item);
//not exactly how you call the Register method, but you get the idea.
}
How would I set up a collection object to achieve the result I'm looking for? I'm having trouble storing both an interface type, and an implementation for it.
It's hard to infer what you're looking for here, but maybe you're looking at some of ServiceStack Funq's IOC late-bound API's? e.g:
container.Register(
new FirstServiceInterfaceImplementation(),
typeof(IFirstServiceInterface));
//or
container.RegisterAutoWiredType(
typeof(FirstServiceInterfaceImplementation),
typeof(IFirstServiceInterface));
In which to use the first API you can use a Dictionary<Type,object>, e.g:
var deps = new Dictionary<Type,object> {
{ typeof(IFirstServiceInterface), new FirstServiceInterfaceImplementation() },
{ typeof(ISecondServiceInterface), new SecondServiceInterfaceImplementation() },
};
Then register like:
foreach (var entry in deps)
{
container.Register(entry.Value, entry.Key);
}

C# Specifying different algorithms/logic flow in configuration file

I would like to specify the functionality of an application in a json file that is passed to the application. This will be used to load different libraries.
For example a dictionary containing:
"RunType1" : {
"Init" : "AlgoInit1",
"Body" : "AlgoBody6",
"End" : "AlgoEnd3"
}
This will load the RunType1 dll and chose these functions.
This could use a set of if / else statements
ie
if (initText == "AlgoInit1")
callAlgoInit1();
else (initText == "AlgoInit2")
callAlgoInit2();
etc
But this would fail if i wanted to add new algos to the library, without recoding this.
Is these a more elegant way of choosing or passing the functions to a generic run structure?
I would like to do something like:
runInitAlgo("AlgoInit1"); // take the actual parameter from the config
runBodyAlgo("AlgoBody6");
runEndAlgo("AlgoEnd3");
What is the best solution/patterns for achieving this in C#? So I dont have to hard-code the algo function names into the body of the application.
Thanks.
You can make a Dictionary:
Dictionary<string, Action>actions = new Dictionary<string, Action>();
void Init(){
actions.Add("Init" ,AlgoInit1);
actions.Add("Body" ,AlgoBody6);
actions.Add("End" ,AlgoEnd3);
}
void Do(string action){
actions[action]();
}
private static void AlgoInit1(){
throw new NotImplementedException();
}
You dictionary can be a static or a member field in your class.
If the name corresponds to a DLL, you can use that kind of logic to load dynamically your DLL and then the corresponding class (which inherits from a known interface known for example "Algo") :
Assembly assembly = Assembly.LoadFrom("RunType1.dll");
Type dllType = assembly.GetType("RunType1.Algo");
Algo obj = Activator.CreateInstance(dllType) as Algo;
obj.Init();
obj.Body();
obj.End();
References :
http://msdn.microsoft.com/fr-fr/library/f7ykdhsy.aspx
[fr]http://populnet.blogspot.fr/2008/12/charger-une-dll-dynamiquement.html
You should work around the Strategy Pattern ( http://en.wikipedia.org/wiki/Strategy_pattern ) which is more or less what you want to do.
For a basic C# implementation of the Strategy Pattern you can refer to this document:
http://www.codeproject.com/Articles/346873/Understanding-and-Implementing-the-Strategy-Patter

What is the alternate of javascript object in c# without using class?

ok, so in javascript, we can declare an object like this,
var obj={name:"Irshu",age:22};
console.log(obj);
How do we do the same in c#? the reason i ask because my function need to return a string and a bool together. I dont want to create a class for it, and i dont want to use the dictionary. Are there any alternatives?
public void Message(){
var obj=GetObject(val);
Messagebox.Show(Convert.ToString(obj.ind));
}
public object GetObject(string val){
return new {ind=val,flag=true};
}
This is not valid, is it?
.Net supports ExpandoObject since .NET 4.
http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject%28v=vs.110%29.aspx
It lets you declare the object and add properties as your would in javascript.
Traditionally it is for JS interop and I can't recommend it for production work. Tuple<T> is more appropriate as you get strong typing for free. Ultimately you will write less code and see less runtime errors.
What you have in your code is an anonymous type. Anonymous types cannot exist outside the scope in which they are declared. Generally, we use these for transforming LINQ results to temporary objects.
You can't return anonymous types from a method. You can do however something like this:
public void Message(){
var obj = new { ind = "oaiwejf", flag = true };
Messagebox.Show(obj.ind);
}
EDIT
Check this MSDN article
turns out, its posible, one genius on the internet posted this:
public void Message()
{
var obj=GetObject("Irshu");
var y= Cast(obj, new { ind= "", flag= true });
Messagebox.Show(y.ind); //alerts Irshu
}
public object GetObject(string val){
return new {ind=val,flag=true};
}
T Cast<T>(object obj, T type)
{
return (T)obj;
}

The following throws 'is a Method but treated like a type'

The most confusing error I have ever seen in ASP. I have done method calls like this before, and have no issue in other spots of my code.
First of all the class:
namespace LocApp.Helpers.Classes.LocationHelper
{
public class QueryHelper
{
private LocAppContext db = new LocAppContext();
public static IEnumerable<Service> getAllService()
{
using (var db = new LocAppContext())
{
var service = db.Locations.Include(s => s.LocationAssignment);
var serv = (from s in db.Services
where s.active == true
select s).ToList();
return serv;
}
}
}
}
Pretty easy to understand whats going on. So lets call the method:
IEnumerable<LocApp.Models.Service> Service = new LocApp.Helpers.Classes.LocationHelper.QueryHelper.getAllService(Model.id);
getAllServices(Model.id) is throwing the error "is a method but treated like a type" , um no its not be treated like a type....
whats going on?
Well it's exactly as the error message says. getAllService() is a method:
public static IEnumerable<Service> getAllService()
But you're trying to use it as if it were a type with a constructor:
Service = new LocApp.Helpers.Classes.LocationHelper.QueryHelper.getAllService(...)
The new part is the mistake here. You don't want to call a constructor, you just want to call a method. It's a static method, so you don't need an instance - you can just use:
Service = LocApp.Helpers.Classes.LocationHelper.QueryHelper.getAllService(...)
Note that if you have appropriate using directives, follow .NET naming conventions and take care about singular/plural names, your code will be easier to follow:
var services = QueryHelper.GetAllServices(...);
Do you not simply mean:
IEnumerable<LocApp.Models.Service> Service = LocApp.Helpers.Classes.LocationHelper.QueryHelper.getAllService();
Get rid of the new bit, essentially, and that method doesn't take any parameters either - I'd assume you'd run into that problem after you removed the new bit.
Your getAllService method doesn't take any arguments, so you should call it without. Also it is a static method so don't use the new keyword:
IEnumerable<LocApp.Models.Service> Service = LocApp.Helpers.Classes.LocationHelper.QueryHelper.getAllService();

C# memcpy equivalent

I have 2 objects from the same type and i would like to shallow copy one state to the other. In C++ i have memcpy which is great. How can i do it in C#? The MemberwiseClone() is not good enough because it creates & returns a new object and i like to copy to an existing object. I thought of using reflection but i'm afraid it will be too slow for production code. I also thought of using one of the .Net serializers but i think they also create object rather than setting an existing one.
My Use Case:
I have a template object (class not struct) which needs to be updated by one of its instances (objects made of this template)
Any ideas?
In C# (and in C++ too), there is no difference between "new object" and "a copy of existing object" as long as all their members equal to each other.
Given:
Int32 a = 5;
, both operations:
Int32 b = 5;
Int32 b = a;
yield the same result.
As stated in MSDN reference:
The MemberwiseClone method creates a shallow copy by creating a new object, and then copying the nonstatic fields of the current object to the new object.
If a field is a value type, a bit-by-bit copy of the field is performed.
If a field is a reference type, the reference is copied but the referred object is not; therefore, the original object and its clone refer to the same object.
, i.e. it does just the same as memcpy() in C++
[edit] regarding your clarification:
As I understand, you have N objects, each has a (direct) reference to the template object. You want to write back to the template so all objects "see" these changes.
Suggestion: imlement a template broker.
class TemplateProvider
{
public MyData Template { get; set; }
}
Instead of passing the template, pass the template provider to the objects.
to simplyfy the syntax in the components, you can add a (private/internal?) property
MyData Template { get { return m_templateProvider.Template; } }
void UpdateTemplate() { m_templateProvider.Template =
(MyData) this.MemberwiseClone(); }
The template provider also simplifies locking in multithreaded scenarios.
In short, no way unless you do it yourself. But why not create a new object if you override all properties anyway?
memcopy and similar low level constructs are not supported since they undermine guarantees made by the environment.
A shallow copy for structs is made by assignment. For classes, MemberwiseClone is the method to do that - but as you say that creates a new object.
There is no built in way for that, and as it potentially breaks encapsulation it should be used with care anyway.
You could build a generic routine using reflection, but whether it works or not depends on the class itself. And yes, ti will be comparedly slow.
What's left is supporting it by a custom interface. You can provide a generic "Shallow Copy" routine that checks for the interface and uses that, and falls back to reflection when it doesn't. This makes the functionality available generally, and you can optimize the classes for which performance matters later.
I guess you could just do something like:
YourObjectType A = new YourObjectType();
YourObjectType B = a.MemberwiseClone();
This will create a new object inside the MemberwiseClone method an make the B object reference it. I guess it serves your purposes.
Assignment of one struct to another, for all intents and purposes, works exactly like memcpy in C++ on POD objects.
If you feel that this doesn't apply in your situation then I can assure you that your C++ code was not standard-conforming (i.e., contained bugs in the form of undefined behaviour). Please specify (in the question) what effect you want to achieve. This will be more useful than talking about replicating undefined behaviour in another language.
namespace WindowsFormsApplication7
{
[Serializable] // just put this in your class
class Mate
{
public string SomeProperty { get; set; }
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var mA = new Mate();
mA.SomeProperty = "Hey";
var vf = new BinaryFormatter();
var ns = new MemoryStream();
vf.Serialize(ns, mA);
byte[] vytes = ns.ToArray();
var vfx = new BinaryFormatter();
var nsx = new MemoryStream();
nsx.Write(vytes, 0, vytes.Length);
nsx.Seek(0, 0);
var mB = (Mate)vfx.Deserialize(nsx);
mA.SomeProperty = "Yo";
MessageBox.Show(mA.SomeProperty); // Yo
MessageBox.Show(mB.SomeProperty); // Hey
}
}
}
C# / .Net memcpy equivalent is Buffer.MemoryCopy .
void MemoryCopy (void* source, void* destination, long destinationSizeInBytes, long sourceBytesToCopy);
https://learn.microsoft.com/en-us/dotnet/api/system.buffer.memorycopy?view=net-5.0
namespace WindowsFormsApplication7
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var dt = new DataTable();
dt.Columns.Add("lastname", typeof(string));
dt.Columns.Add("firstname", typeof(string));
dt.Rows.Add("lennon", "john");
dt.Rows.Add("mccartney", "paul");
var ms = new MemoryStream();
var bf = new BinaryFormatter();
bf.Serialize(ms, dt);
byte[] bytes = ms.ToArray();
var bfx = new BinaryFormatter();
var msx = new MemoryStream();
msx.Write(bytes, 0, bytes.Length);
msx.Seek(0, 0);
// doesn't just copy reference, copy all contents
var dtx = (DataTable)bfx.Deserialize(msx);
dtx.Rows[0]["lastname"] = "Ono";
// just copy reference
var dty = dt;
dty.Rows[0]["lastname"] = "Winston";
MessageBox.Show(dt.Rows[0]["lastname"].ToString()); // Winston
MessageBox.Show(dtx.Rows[0]["lastname"].ToString()); // Ono
MessageBox.Show(dty.Rows[0]["lastname"].ToString()); // Winston
}
}
}

Categories