Is there a way to collect (e.g. in a List) multiple 'generic' objects that don't share a common super class? If so, how can I access their common properties?
For example:
class MyObject<T>
{
public T Value { get; set; }
public string Name { get; set; }
public MyObject(string name, T value)
{
Name = name;
Value = value;
}
}
var fst = new MyObject<int>("fst", 42);
var snd = new MyObject<bool>("snd", true);
List<MyObject<?>> list = new List<MyObject<?>>(){fst, snd};
foreach (MyObject<?> o in list)
Console.WriteLine(o.Name);
Obviously, this is pseudo code, this doesn't work.
Also I don't need to access the .Value property (since that wouldn't be type-safe).
EDIT: Now that I've been thinking about this, It would be possible to use sub-classes for this. However, I think that would mean I'd have to write a new subclass for every new type.
#Grzenio
Yes, that exactly answered my question. Of course, now I need to duplicate the entire shared interface, but that's not a big problem. I should have thought of that...
#aku
You are right about the duck typing. I wouldn't expect two completely random types of objects to be accessible.
But I thought generic objects would share some kind of common interface, since they are exactly the same, apart from the type they are parametrized by. Apparently, this is not the case automatically.
I don't think it is possible in C#, because MyObject is not a baseclass of MyObject. What I usually do is to define an interface (a 'normal' one, not generic) and make MyObject implement that interface, e.g.
interface INamedObject
{
string Name {get;}
}
and then you can use the interface:
List<INamedObject> list = new List<INamedObject>(){fst, snd};
foreach (INamedObject o in list)
Console.WriteLine(o.Name);
Did it answer your question?
C# doesn't support duck typing. You have 2 choices: interfaces and inheritance, otherwise you can't access similar properties of different types of objects.
The best way would be to add a common base class, otherwise you can fall back to reflection.
Related
I want to create a nested structure where every class represents a country, inheriting the same parent class Country. Each child class should have an enum representing the different states States.
The goal is being able to select a country, then one of its states.
The Content will be saved into a dictionary Dictionary<Tuple<string, Type>, object> where the Types would be Country and Country.States.
I tried making an interface/abstract class with an enum called States to be implemented, but this does not work, as it is a type definition.
Is there any workaround?
public abstract class Country
{
public abstract enum States { get; }
}
public class CountryA : Country
{
public new enum States
{
StateA,
StateB,
StateC,
}
}
Your design is flawed, you need to create a single Country class with a property e.g. public string[] States { get; set; }.
Then create instances (objects) of your Country class, each with States set to the items that are needed:
var usa = new Country { Name = "USA", States = new[] { "Alabama", ... } };
var canada = new Country { Name = "Canada", States = new[] { ... } };
// etc
You have a few options:
You can create an enum at runtime (see here: Dynamically create an enum), but I don't think that'll suit your needs, as I imagine you're going down the enum route for ease of use in coding than anything else.
You could implement a typesafe enum pattern (see here: typesafe enum pattern), but that's even more coding just for the ability to use a design that mimics enums while your coding the rest of your logic.
My advice is to use a dictionary and build your 'states' at instantiation from a settings file or external data source. After all, countries and their states/cities/etc do change names from time to time. Locking yourself into a hard-coded situation like what you're aiming for isn't going to support such future changes.
Good luck!
[Edited following response from camilo-terevinto]
While I certainly agree that your design is most likely flawed, since you'd need hundreds of classes and enums, I disagree entirely with the other answers that "it is not possible".
It's certainly possible using generics (while keeping in mind you cannot restrict entirely to Enums):
public abstract class Country<TStates>
where TStates: struct, IConvertible, IFormattable, IComparable
{
public abstract TStates[] States { get; }
}
public enum UnitedStatesStates
{
WhoCares, WhoCares2
}
public class UnitedStatesCountry : Country<UnitedStatesStates>
{
public override UnitedStatesStates[] States { get; }
}
Now, I highly doubt this will be useful in the (not-so-long) term.
You are asking to make enum inheritable, this is possible to achieve if you don't use enum, but a class with static public members (which can be inherited and have different set of members per type). It behave nearly as enum:
public class Country1
{
public static State State1 { get; } = new State("State 1");
public static State State2 { get; } = new State("State 2");
...
}
It should be clear what Country1.State1 is, right? The State can be a more complex object than just a string. It doesn't require inheritance as you can see, because country define states as different members.
You can follow same principle to implement long chain of objects: Planet.Continent.Country.State.Province.Town.Street.Hause..
You say
Content will be saved into a dictionary Dictionary<Tuple<string, Type>, object> where the Types would be Country and Country.States.
Don't. Those are different types, that's a poor choice of a key. If you need to enumerate (to find) states, then just add another member to a Country:
public static IEnumerable<State> States
{
get
{
yield return State1;
yield return State2;
...
}
}
Then the searching for something can be a simple linq:
var stateAInCountry1 = ...Countries.OfType<Contry1>().Single().States.Single(o => o.Name == "A");
var countriesWithStateA = ...Countries.Where(o => o.States.Any(o => o.Name == "A"));
Not sure what problem are you solving by introducing a dictionary, but you can initialize additional data structure with proper key if you provided a way to iterate with easy.
It is not so clear to me, if there is anything else you want to achieve, besides being reminded by the compiler to define these different (!) enums.
Actually they have nothing in common to begin with, so neither the compiler nor you can draw any advantage of that contract.
What you could do is declare it as
public abstract string[] States {get;}
and obtain these strings from the individual enums you define in the derived classes. Then the common thing would probably be that you want the string result for informative purposes or something.
I have a set of class objects that I can not touch. All of them have an ID property that I would like to access in other functions in a generic way.
For simplicities sake here is an example of my problem.
class Example1 {
int ID { get; set;}
}
class Example2 {
int ID { get; set; }
}
I am not able to edit either of these two classes or the library they are in.
I also have a function that expects an ID that can come from either Example1 or Example2. In order to handle this I have come up with a number of solutions but am curious what the proper way to solve this would be.
I could:
Use dynamic classes to access the various classes ID's.
Use reflection to pull out an ID parameter from any given type.
Use an odd inheritance by creating a new class so that Example1ViewModel : Example1, IIdentifiableObject and then expect IIdentifiableObject in my function and implement a copy constructor in Example1ViewModel to handle collecting the data
Write a separate filter function that can extract out the relevant parts from either class and provide the results.
None of these solutions seem particularly good to me. How should I be handling a many to one relationship like this in code and are there tools that C# provides to handle this?
possible solution using extension methods for the classes
public static class MyExtensions
{
public static int GetId(this Example1 ex)
{
return ex.Id;
}
public static int GetId(this Example2 ex)
{
return ex.Id;
}
}
You can add a static method using reflection:
public static int GetId(object obj)
{
Type type = obj.GetType();
return Convert.ToInt32(type.GetProperty("ID").GetValue(obj, null));
}
Then you can invoke it with any object to get the id property value.
Here is the solution that we ended up using and why.
We are using an inheritence structure that that takes the following two base classes:
FooExample
BarExample
and wraps them in the following
IExample
FooExampleModel : IExample
BarExampleModel : IExample
Both FooExampleModel and BarExampleModel have constructors which accept the class they are wrapping.
The importance of this is that it allows us to create methods accepting IExample instances without having to manipulate data beforehand. Additionally, unlike using dynamic types or reflection this solution provides us with compile time error checking.
Unfortunately using extension methods does not work. While it allows us to call the same method on two different object types like we wanted it does not allow those objects to be passed as Generic types to a seperate function.
The result of all of this is that this is now possible:
var foos = new List<FooExample>(); //Pretend there is data here
var bars = new List<BarExample>();
var examples = foos.Select((foo) => (IExample)new FooExampleModel(foo))
.Concat(bars.Select((bar) => (IExample)new BarExampleModel(bar)))
.ToList(); // Force evaluation before function call
DoSomethingOnIExamples(examples);
Besides that slightly gross LINQ query this appears to be the best way to accomplish this (DoSomethingOnIExamples(...) is a function accepting an IEnumerable<IExample> argument). Obviously this solution gets less nice as more types are added to this mix.
I have a solution that works, but for educational purposes I want to understand if there is a better/cleaner/right way to do it.
Problem: In my "client" app I have a dictionary Dictionary<String, PremiseObject> where the key (String) is a immutable URL to a resource (it's actually a REST URL). PremiseObject is the base type of a whole set of derived classes; thus the Dictionary actually contains a family of classes all derived from PremiseObject.
A key requirement is I want to try to 'guarantee' that no PremiseObjects get created OUTSIDE of the dictionary.
Solution: I have the following function for getting a object out of the dictionary. It either accesses the existing instance, or if it does not exist creates it:
public PremiseObject GetOrCreateServerObject(string premiseObjectType, string location)
{
PremiseObject po = null;
if (!premiseObjects.TryGetValue(location, out po))
{
string classname;
// Create an instance of the right PremiseObject derived class:
po = // gobbly-gook that is not relevant to this question.
premiseObjects.Add(location, po);
}
else
{
Debug.WriteLine("Already exists: {0}", location);
}
return po;
}
Callers do this:
DoorSensor door =
(DoorSensor)server.GetOrCreateServerObject("DoorSensor",
"http://xyz/FrontDoor");
Works great. But I think there's a pattern or design that would elegantly allow me to encapsulate the "single-instance of each object contained in the dictionary" more.
For example, callers could do this:
DoorSensor door = null;
if (!server.ServerObjects.TryGetValue("DoorSensor",
"http://xyz/FrontDoor",
out door))
Debug.WriteLine("Something went very wrong");
I'm not really what to call this pattern. My ServerObjects are "single-instanced" by location. And my GetOrCreateServerObject is like a factory that lazy creates.
But it's possible for instances to be created that don't get put into the dictionary, which could lead to problems.
Like I said, what I have works... Cheers!
UPDATE 1/26/2011 10:13PM -
I just realized a potential problem: On the server side the object represented by a location/URL can actually be multi-inherited. It is THEORETICALLY possible for an object to be both a DoorSensor and an DigitalRelay.
I currently don't care about any of those cases (e.g. for garage doors I simplified my example above; there really is no DoorSensor I exposed, just a GarageDoorOpener which includes BOTH properties for sensing (e.g. Status) and actuation (e.g. Trigger). But this puts a wrinkle in my whole scheme if I were to care. Since this project is just for me :-) I am going to declare I don't care and document it.
I would propose the following simple idea:
PremiseObject's constructor is declared internal.
A special factory object is responsible for creating (or returning an already created) instances. The dictionary is a part of the factory.
Clients are located in another assembly.
This way PremiseObjects can be created by clients only through the factory. This way you can guarantee that only single instance of object exists for each location.
A variant of the idea would be to declare the PremiseObject's constructor private, and declare the factory a friend; but (unlike C++) C# doesn't have a friend notion.
Ok you can probably avoid a parameter and a cast (in the consumer code any way) with a generic method.
public abstract class PremiseObject
{
protected PremiseObject()
{
}
public string Location { get; set; }
public static void GetSensor<T>(string location, out T sensor)
where T : PremiseObject, new()
{
PremiseObject so;
if(_locationSingltons.TryGetValue(location, out so))
{
sensor = (T) so; // this will throw and exception if the
// wrong type has been created.
return;
}
sensor = new T();
sensor.Location = location;
_locationSingltons.Add(location, sensor);
}
private static Dictionary<string, PremiseObject> _locationSingltons
= new Dictionary<string, PremiseObject>();
}
Then the calling code looks a bit nicer:
DoorSensor frontDoor;
PremiseObject.GetSensor("http://FrontDoor/etc", out frontDoor);
So I like that calling convention - if you want to stay away from throwing an exception you can change the return type to bool and indicate failure that way. Personally I wouls say that an exception is what you want.
You may prefer the call without the out parameter - but if you do that then you have to supply the type to the method call - anyway defining the factory method would look like this:
public static T GetSensor<T>(string location) where T : PremiseObject, new()
{
PremiseObject so;
if (_locationSingltons.TryGetValue(location, out so))
{
return (T)so; // this will throw and exception if the
// wrong type has been created.
}
T result = new T();
result.Location = location;
_locationSingltons.Add(location, result);
return result;
}
Then the calling code looks like this:
var frontDoor2 = PremiseObject.GetSensor<DoorSensor>("http://FrontDoor/etc");
I like both these approaches because nothing has to be repeated. The type of the PremiseObject only gets stated once - there is no need for a string defining the type.
If you want to be really, really sure that no instances of PremiseObject get created that aren't placed in the dictionary, you could make the constructors all private, and create a static constructor (for each subclass) that took as a parameter the Dictionary object you're referring to. This static constructor would check the dictionary object to make sure that there wasn't an existing instance, and then return either the new or the existing instance as required. So something like this:
public class PremiseObject
{
public static Dictionary<string, PremiseObject> PremiseObjects { get; private set; }
static PremiseObject()
{
PremiseObjects = new Dictionary<string, PremiseObject>();
}
}
public class DerivedPremiseObject : PremiseObject
{
private DerivedPremiseObject()
{
}
public static DerivedPremiseObject GetDerivedPremiseObject(string location)
{
DerivedPremiseObject po = null;
if (!PremiseObject.PremiseObjects.TryGetValue(location, out po))
{
po = new DerivedPremiseObject();
PremiseObject.PremiseObjects.Add(location, po);
}
return po;
}
}
And there are a variety of similar strategies you could use. The key is to somehow make the constructor private and only allow access to the constructor through a static method that enforces the logic of the class construction.
Perhaps you could make PremiseObject a singleton, then you wouldn't have to worry about each object in the dictionary beign a single instance?
In the general case, setting access modifiers on your constructors should do the trick of not allowing anyone external to create the objects (barring reflection). However, these would need to be internal, so anything else in the assembly would be able to instantiate them.
I suspect many of your requirements may be met by using an off the shelf dependency injection container that supports singleton instances. It feels close, but maybe not quite the same. (possibly StrutureMap, Ninject, Castle Windsor, or Unity in no particular order)
Take this example:
interface IEntity {
string Name { get; set; }
}
class Product : IEntity {
public string Name { get; set; }
public int Count { get; set; } // added member
}
class Client {
void Process() {
var product = new Product();
int count = product.Count; // this is valid
}
}
In the example above, what is the type of product? Is it IEntity or Product? It appears that product is of type concrete implementation (Product). If that is the case, shouldn't var be used only in special circumstances. But I see that tools like resharper recommend using var by default. Shouldn't one program to an interface?
You are not actually "programming to interfaces" if you are still instantiating the concrete class within the method, as the dependency to the concrete Product class still remains. In order to properly program-to-interfaces you must remove the new instantiation, for example by using a factory or IoC.
What if you had a Product like ...
class Product : IFirst, ISecond, IThrid
The only rational thing the complier can do is what it does. I don't limit my use of var, I use it everywhere. I think it makes code far more readable. In this case, I agree with ReSharper across the board.
If you want Product to be of type IEntity, try this:
var product = new Product() as IEntity;
That said, yes you should program to an interface, but in your case you're instantiating the concrete type directly. If you've already created a dependency to the concrete type, just use the concrete type. If not, use a factory or injection to get an instance of the interface. var will work with those rather well. For example:
public class MyExtremelySimpleFactoryExampleClass
{
public IEntity Instantiate()
{
return new Product();
}
}
// elsewhere in your code...
var item = myFactory.Instantiate(); // item is of type IEntity
Finally, no, I don't think var should be used only in "special circumstances". I find it quite useful and use it almost always.
var product = new Product() is of type Product. You could program to the interface if you weren't using members outside that interface (Product.Count isn't on the IEntity interface).
Added:
Also, in VS2008, you can hover over the var keyword in the declaration to see the implied type. This hover/tooltip message also works on the variable name after the declaration line. (from C# In Depth, page 211)
The type that is inferred is the actual type, not any interface or base class that it may implement/inherit.
Consider this:
var answer = "42";
If it would infer an interface rather than the type, the variable type would be something like IComparable instead of string.
The usage of the var keyword relies on it inferring the actual type, or it would not make sense to use it for anything other than anonymous types. As long as the type is obvious you can use it to make the code more readable, but if the type is not completely obvious, you should avoid using it. (My example above is in the gray area, as it does not actually contain the string type name.)
If you use var in this instance, it will be of type Product. I don't like using var by default, as it can make reading code a little confusing at times.
I prefer using var mostly in LINQ queries, but try not to overuse it in other places (like your example). For people using an IDE with intellisense it is fine, but if you are ever reading the code with Notepad (or Notepad++, etc.), you will have a harder time figuring out the type without a little research.
Is it possible to allow methods and properties of the 'this' pointer to be resolved dynamically?
Put another way, can a class have a dynamic superclass?
Clarification
I would like to be able to subclass some class and access properties and methods that aren't defined at compile-time.
class MyClass : DynamicObject
{
public void ReceiveValue(object value) {
MyProperty = value;
}
}
DynamicObject provides a way for my code to get notified that set_MyProperty has been called with the argument value above, correct? I know this is possible if you use a syntax like:
var mc = new MyClass();
...
dynamic dmc = mc;
dmc.MyProperty = value;
But I want to be able to do this from within the methods of MyClass, almost as if I had done:
dynamic dmc = this;
dmc.MyProperty = value;
Does DynamicObject have me covered?
No, you can't have a dynamic base class. Aside from anything else, the system still needs to know how much space to allocate when you create a new instance of your class.
Could you explain what you're trying to achieve? There may well be ways in which dynamic would help without needing quite this behaviour.
EDIT: Okay, having seen your edit - I don't think you can quite do what you want, but if you just use the
dynamic dmc = this;
dmc.MyProperty = value;
or
((dynamic)this).MyProperty = value;
workaround it should be fine. To put it another way: the this reference is always statically typed, but you can have an expression with the value of this but with a dynamic type.
That shouldn't be too onerous unless you're doing a lot of dynamic work - in which case I'd recommend that you use a fully dynamic language instead. If you implement the bulk of your dynamic code in IronPython/IronRuby, you can easily integrate it with your C# code anyway.
This is the basis of polymorphism. The method/property called will be the one given lowest in the heirarchy of the objects type.
How about this:
class B
{
public void M(object o)
{
dynamic i = this;
i.P = o;
}
}
class D : B
{
public object P { get; set; }
}
class Program
{
static void Main()
{
var d = new D();
d.M(1);
}
}
I realize this is a tangent, but there are languages where every class's superclass is dynamic - i.e. where class name resolution is virtual and override-able.