I have a class which is handling objects same way.
It's like:
class Handler<T>{
private T _obj;
public T obj{
get{
...//do sth
return _obj;
}
set{
...//do sth
_obj = value;
}
}
... // some other properties, no T anymore
}
There are large amount of code working on Handler objects, ignoring type. I mean, type T is not for them, there are setting other fields.
There are containers with Handler<> and so on.
At the end I need to return Handler with correct type.
I wanted to use Handler<object>, but there is no way I know to convert it to Handler<SomeClass>.
How can I handle situtations like this?
Why don't you make a base class for Handler<T>, which will contain all non-generic code?
class HandlerBase
{
// some other properties
}
class Handler<T> : HandlerBase
{
public T obj { ... }
}
If your "large amount of code" ignores T, than let it work with HandlerBase.
You can try with an IHandler interface.
IHandler<SomeClass> h1 = new Handler<SomeClass>();
IHandler<Object> h2 = h1;
This will work !
More info on Covariance on MSDN
Related
I'm trying to access a field from a derived class in an array that holds references to the base class.
I have three classes:
abstract GameObjectBase
{
}
And derived from that are:
public Gamespace: GameObjectBase
{
private bool containsItem;
}
And:
public GameWall: GameObjectBase
{
}
(Obviously these classes hold more data, methods, and constructors).
I have created an array from these objects, like this
private GameObjectBase[,] _labyrinthArray = new GameObjectBase[10,10];
I then fill said array with Gamespaces and Gamewalls. But when I access a Gamespace object in the array, the containsItem field is not accessible due to the reference to the object being of type GameObjectBase.
Obviously I could put containsItem in GameObjectBase and make it accessible from there, but that doesn't fit my OOP approach. The only other solution I have found is to cast the object in question explicitely to Gamespace.
That seems quite crude and error prone to me. Is there any better solution to this?
First of all, you cannot reference a private field from outside the object class itself. You probably want to use a read-only property to encapsulate the field. If you don't want to cast the object explicitly to a Gamespace, you could use an interface instead.
public interface ICanContainItem
{
bool ContainsItem { get; }
}
public class Gamespace : GameObjectBase, ICanContainItem
{
private bool _containsItem;
public bool ContainsItem
{
get { return _containsItem; }
private set { _containsItem = value; }
}
}
This way you can then check whether the object "can contain an item" or not through the interface. Even if in the future you add new types of spaces that can contain an item, this same piece of code works, if the new types also implement the same interface.
var gameObject = _labyrinthArray[i,j]; //i,j defined elsewhere
var mayContainItem = gameObject as ICanContainItem;
if (mayContainItem != null)
{
var itemExists = mayContainItem.ContainsItem;
//mayContainItem.ContainsItem = false; //<-- fails because there's no setter
}
Let's say I have a Class:
class AbstractPerson{
AbstractAttribute attr {get; set;}
}
Now, in the child Class of AbstractPerson, I want to use the attr but, in the special case like so:
class Pilot: AbstractPerson {
...
(attr as SpecialAttribute).pilotID;
...
}
Because I don't want to do this, everytime I call attr, I want to have a property in Pilot that gives back a typecasted version of attr, but I'm not getting this to work.
So, this doesn't work:
class Pilot: AbstractPerson {
AbstractAttribute attr {
get
{
return (attr as SpecialAttribute);
}
set;
}
}
Is this even possible?
*** I know that by convention, "attr" should be in PascalCase, I just forgot for this example. In reality the Person is a Controller and the attr a View.
Assuming, that:
class SpecialAttribute : AbstractAttribute {}
You can use generics:
class AbstractPerson<T>
where T : AbstractAttribute
{
T attr {get; set;}
}
class Pilot: AbstractPerson<SpecialAttribute>
{
/* ... */
void Foo()
{
// attr is a SpecialAttribute here
attr.PropertyOfSpecialAttribute = "bar";
}
}
Note, that you're misusing as operator.
If there is a possibility, that attr isn't a SpecialAttribute, than as must be followed by null-checking:
var foo = bar as Foo;
if (foo != null)
{
// do something
}
Otherwise (if attr must be SpecialAttribute), you must use type casting:
var foo = (Foo)bar;
to throw InvalidCastException, if the type is not expected.
In this kind of situation, I prefer Dennis's suggestion. That said, you may not be able to change the base class to use it. If that's the case, then you can do something not quite as good but still useful:
class AbstractPerson
{
AbstractAttribute Attribute { get; set; }
}
class Pilot : AbstractPerson
{
PilotAttribute PilotAttribute
{
get { return (PilotAttribute)AbstractAttribute; }
set { AbstractAttribute = value; }
}
}
Naturally, this approach requires that PilotAttribute actually derive from AbstractAttribute, something that is not actually required in the generic solution (unless you specifically want it to be). It also does not provide the level of security that the generic solution does: the AbstractAttribute is still present and could be assigned a value not of the PilotAttribute type. So you do have to be careful to not do that (preferably by avoiding using the base attribute when dealing with instances of Pilot).
It is also possible to simply hide the base AbstractAttribute property with a new one. But I detest member hiding and IMHO all that would do here is make the code more confusing.
In C# I know we can't we assign objects to an Enum. The functionality I'm after is when an Enum is declared, it triggers off an event.
So instead of having
enum MyEnum
{
string, int, etc
}
I could have
enum MyEnum
{
classType1, classType2
}
This would then also allow the classes classType1/classType2 constructor to be called which could (for example) be useful for logging for when the enum is declared.
Another way of presenting my issue could be
enum MyEnum
{
string1
{
//logic
},
string2
{
//logic
}
}
Is there a work around for this?
Instead of enum you can use a static class with static properties, it can be used same as an enum but you can write code inside getter and setter.
U could use properties instead of enum (then u can write ur own logic which will be called after/before assigning the variable). The enum structure should be used to create flags-like stuff.
private string _myVar;
public string MyVar
{
get { return _myVar; }
set
{
// logic 1 here
_myVar = value;
// logic 2 here
}
}
No work around as, I think, your expectation does not match the language. For example consider what would happen with:
if (myEnumValue == MyEnum.classType1)
Your question implies that on the right a class of 'classType1' would be instantiated for the equality test and then the result would depend on that types implementation of equality. This is confusing when the item on the left is an enum ... but with your assumption it is an object of type 'classType1' which implies that both the left and right are temporary objects.
You can see that this could not work.
But ... what I think your really after is a factory to create objects from an enum. Whole other question that raised other questions (sorry). An enum like this implies a state ... so if you have a state why does that state need an enum? A big question in itself, check out the state pattern.
Hope I've helped.
An enum is a Value type based on an Int## type. So this is the same as asking: can I get some logic into the assignment of int i = 7; and the direct answer is No.
Neither can you base an enum on anything other than an integer type.
But your requirement seems to be with tracking instances. That's easy with properties. But you can only do it for a specific property, not build it into the Type.
Enums are barely integers with comprehensive labels. As far as I know, what you are looking for cannot be done using enums.
However, and as stated by #Grumbler85, this behavior can be simulated using factories.
A factory is a special type of object that are used to create instances of other objects.
The easiest way to implement a factory is using a switch statement but other ways exists (reflection for example). Here's a simple example of what you are looking for:
Class A
{
...
}
Class B
{
...
}
enum eKnownTypes
{
A,
B
}
Class Factory
{
/*
Implement Singleton here
....
*/
public object CreateInstance(eKnownTypes t)
{
/*
Raise any event needed here
...
*/
switch (t):
{
case eKnownTypes.A: return new A(); break;
case eKnownTypes.B: return new B(); break;
}
return null;
}
}
/*
Set Event Handlers here
Factory.Instance.CustomEvent += new EventHandler ...
....
*/
A objectA = Factory.Instance.CreateInstance(eKnownTypes.A) as A;
...
You can do it with an enum, but you could do
public struct MyType
{
public const int OneValue = 1;
public const int TwoValue = 2;
private static readonly MyType one = new MyType(OneValue);
private static readonly MyType two = new MyType(TwoValue);
private readonly value int;
private MyType(int value)
{
this.value = value;
}
public static One
{
get { return this.one; }
}
public static Two
{
get { return this.two; }
}
public static implicit operator int(MyType source)
{
return source.value;
}
}
To give you a class that behaves like an enum but is fully extendable.
for instance, you can do
var myType = MyType.One;
switch (myType)
{
case MyType.OneValue:
...
case MyType.TwoValue:
...
default:
...
}
The instances are immutable and can be accuarately tested for equality using the implemenation inhereted from object, i.e. reference quality.
I swear I have seen an example of this but have been googling for a bit and can not find it.
I have a class that has a reference to an object and need to have a GET; method for it. My problem is that I do not want anyone to be able to fiddle with it, i.e. I want them to get a read only version of it, (note I need to be able to alter it from within my class).
Thanks
No, there's no way of doing this. For instance, if you return a List<string> (and it's not immutable) then callers will be able to add entries.
The normal way round this is to return an immutable wrapper, e.g. ReadOnlyCollection<T>.
For other mutable types, you may need to clone the value before returning it.
Note that just returning an immutable interface view (e.g. returning IEnumerable<T> instead of List<T>) won't stop a caller from casting back to the mutable type and mutating.
EDIT: Note that apart from anything else, this kind of concern is one of the reasons why immutable types make it easier to reason about code :)
Return a reference to a stripped-down interface:
interface IFoo
string Bar { get; }
class ClassWithGet
public IFoo GetFoo(...);
If the object isn't too complicated/extensive then write an wrapper around it.
for example:
class A {
public string strField = 'string';
public int intField = 10;
}
class AWrapper {
private A _aObj;
public AWrapper(A aobj) {
_aObj = A;
}
public string strField {
get {
return _aObj.strField;
}
}
public int intField {
get {
return _aObj.intField;
}
}
}
So now all you do is give your client code an instance of the AWrapper class so that they may only use what you allow them to see.
this may get a bit complicated and may not scale well if your base class is not set in stone, but for most simple situation it may just do the trick. I think this is called a facade pattern(but don't quote me on that =) )
This isn't possible. Get and set accessors to reference types get and set the reference to the object. You can prevent changes to the reference by using a private (or internal) setter, but you cannot prevent changes to the object itself if it's exposed by a getter.
Your question reads like you're looking for:
public PropertyName { get; private set; }
But then, given the answers so far I'm not sure I'm interpreting your question correctly. Besides, who am I to question Jon Skeet? :)
i agree with ReadOnlyCollection
See my simple code:
private List<Device> _devices;
public readonly System.Collections.ObjectModel.ReadOnlyCollection<Device> Devices
{
get
{
return (_devices.AsReadOnly());
}
}
ReadOnlyCollection dosen't has Add method so user cant add properties to it.BUT ther is no warranty that if user can modify objects by calling their methods....
I have faced this problem in a certain way.
I have a CategoryViewModel class, which have a property Category that I want private read-only :
public CategoryViewModel
{
private Category { get; }
}
In fact, I want it to be exported as read-only to other class. However I can't do such thing.
In my case (maybe it will help some other guys), I want to add it to a repository. The only way that I've found is to have a function with the repository as param 1, and an Action as param 2 :
public void ApplyAction(ICategoryRepository repo, Action<ICategoryRepository, Category> action)
{
action(repo, Category);
}
Like that, from elsewhere, I can do such thing :
categoryViewModel.ApplyAction(_repository, (r, c) => r.MarkForInsertOrUpdate(c));
This can help other to expose there property only for certains cases and can manage them.
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.