Get value from inheritance out of a collection - c#

I created classes that derive from a parent class looking like this.
class Usability
{
public string useName = "404";
}
and
class Heal : Usability
{
public string useName = "drink";
}
when putting multiple in a Dictionary
public Dictionary<int, Usability> useDict = new();
and then accessing useName via
foreach(var usability in item.usabilitys)
{
Console.Write(usability.useName);
}
allways prints "404". When using
foreach(Heal usability in item.usabilitys)
{
Console.Write(usability.useName);
}
instead prints "drink". There are functions and more data included in sub classes but this breaks down the problem as much as possible.

useName is the field, and fields can't be inherited.
You can use the properties instead of the fields:
public class Base
{
public virtual string Name { get; } = "404";
}
public class Inheritor : Base
{
public override string Name { get; } = "drink";
}
You must mark the base property as a virtual to override it in the class Inheritor.
Properties is just syntax sugar to getter and setter methods, so the property Name is really compiled to the method get_Name.
When you mark the property as the virtual you really make virtual method get_Name and you can override it.

Related

Automatically assign members and methods to certain classes

I have many classes that have the following members/methods:
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public bool isNamed(String name) { return getName().Equals(name); }
Every time I create a new class that has a member "name", I have to rewrite all these.
Is there a way to write the methods one time and to make them apply to any class I want?
Your code can be converted to:
public String Name { get;set;}
Then you can use it as so:
nObject.Name = "Stefan";
if(nObject.Name == "Stefan"){
// do something
}else{
// do something else
}
To apply to all the classes automatically you can just make this into an interface:
public interface INameable{
public String Name {get;set;}
}
Doing this will allow you to inherit from other base classes of importance.
see here for an example
class YourClass : INameable{
//implementation
}
And now, YourClass has "Name" property automatically inserted.
You'd simply define a base class (you could make it abstract):
public abstract class Named
{
public string Name { get; set; }
}
and inherit from it:
public class Person : Named
{
}
You don't really need isNamed as in C#, it is perfectly safe to compare strings with ==.
If your class already inherits from another class which is not Named, you'll have to manually add the Name auto property or resort to simulated multiple inheritance.
Alternatively, you could create a specific modification of Named for every base class:
public abstract class NamedLifeForm : LifeForm
{
public string Name { get; set; }
}
public class Person : NamedLifeForm
{
// Person inherits both a Name and all relevant members of LifeForm
}
Another alternative would be to create a generic wrapper, Named<T>, that would have two properties: the Name and an instance of T. But that would make construction and access cumbersome, so I don't recommend it.
C# has AutoProperties just for that:
public String Name {get; set; }
This handles both the getName() and the setName() you talked about.
Usage:
To set a value: Name = "MyName;
To get a value: string theName = Name;
I'd suggest reading up on Object Oriented Programming. You can save yourself a lot of time and effort (and heckling). Here is a good primer http://www.amazon.com/Beginning-Object-Oriented-Programming-Dan-Clark/dp/1430235306
To answer your specific question, you should read about inheritance. It lets you define a "Parent" class with functions. Then you can inherit with "Child" classes and have those same functions.
http://msdn.microsoft.com/en-us/library/ms173149(v=vs.80).aspx
Here is a code example
public class PersonBase
{
private String name;
public String getName()
{
return this.name;
}
public void setName(string name)
{
this.name = name;
}
public bool isNamed(string name)
{
return this.name.Equals(name);
}
}
public class Employee : PersonBase
{
}
Employee will now have whatever was defined by PersonBase.
As others have pointed out, you can simplify you code with properties. Also you should check for null values before using "this.name".
Here is a link to what properties are:
http://msdn.microsoft.com/en-us/library/x9fsa0sw(v=vs.80).aspx
The simplified code example would be:
public class PersonBase
{
public String Name { get; set; }
}
public class Employee : PersonBase
{
}
I hope this helps get you pointed in the right direction for learning about these concepts.

Specify interface member not by name but type

I have a lot of similar classes generated by svcutil from some external WSDL file. Any class has a Header property and string property which named class name + "1".
For instance, I have classes: SimpleRequest that has Header property and SimpleRequest1 property.
Another one is ComplexRequest that has Header property and ComplexRequest1 property.
So, I want to create a common interface for such classes. So, basically I can define something like that:
interface ISomeRequestClass {
string Header;
// here is some definition for `class name + "1"` properties...
}
Is it possible to define such member in interface?
Here is post edit goes...
Here is sample of generated class:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
public partial class SimpleRequest
{
public string Header;
[System.ServiceModel.MessageBodyMemberAttribute(Name="SimpleRequest", Namespace="data", Order=0)]
public SimpleRequestMsg SimpleRequest1;
public SimpleRequest()
{
}
public SimpleRequest(string Header, SimpleRequestMsg SimpleRequest1)
{
this.Header = Header;
this.SimpleRequest1 = SimpleRequest1;
}
}
POST EDIT 2
I changed definition of this annoying +1 property to represent real actual picture. It's all has different class types. So how can I pull it out to common interface?
POST EDIT 3
Here is coupled question that could bring more clarify.
EDIT (after seeing your code sample): Technically speaking, your code does not have a Header property, it has a Header field. This is an important difference, since you cannot specify fields in an interface. However, using the method described below, you can add properties to your classes that return the field values.
Is it possible to define such member in interface?
No, interface names cannot be dynamic. Anyway, such an interface would not be very useful. If you had an instance of class ISomeRequestClass, what name would you use to access that property?
You can, however, use explicit interface implementation:
interface ISomeRequestClass {
string Header { get; set; }
string ClassName1 { get; set; }
}
class SomeClass : ISomeRequestClass {
string Header { ... }
string SomeClass1 { ... }
// new: explicit interface implementation
string ISomeRequestClass.ClassName1 {
get { return SomeClass1; }
set { SomeClass1 = value; }
}
}
You could define your interface more generally:
interface ISomeRequestClass {
string HeaderProp {get; set;}
string Prop {get; set;}
}
And your concrete classes could be extended (in an extra code file) by mapping interface members to class fields like so:
public partial class SimpleRequest : ISomeRequestClass
{
public string HeaderProp
{
get
{
return Header;
}
set
{
Header = value;
}
}
public string Prop
{
get
{
return SimpleRequest1;
}
set
{
SimpleRequest1= value;
}
}
}
Putting aside for a moment the naming of your classes and properties.
If you're looking to create an interface with a property relevant to your specific +1 type, you have a couple of options.
Use a base class for your +1's
If both of your +1 classes inherit from the same base class you can use this in your interface definition:
public interface IFoo
{
[...]
PlusOneBaseType MyPlusOneObject{get;set;}
}
Create a generic property on your interface
This method allows you to specify the type for the +1 property as a generic parameter:
public interface IFoo<TPlusOneType>
{
[...]
TPlusOneType MyPlusOneObject{get;set;}
}
Which you might use like:
public class SimpleRequest : IFoo<SimpleRequest1>
{
[...]
}
Update
Given that your classes are partial classes, you could always create a second (non machine generated) version of the partial class that impliments your interface.
You mentioned svcutil so I assume you are using these classes as WCF DataContracts?
If that is the case then you could make use the name property of DataMemberAttribute.
interface IRequest
{
string Header { get; set; }
string Request1 { get; set; }
}
[DataContract]
class SimpleRequest : IRequest
{
[DataMember]
public string Header { get; set; }
[DataMember(Name="SimpleRequest1"]
public string Request1 { get; set; }
}
[DataContract]
class ComplexRequest : IRequest
{
[DataMember]
public string Header { get; set; }
[DataMember(Name="ComplexRequest1"]
public string Request1 { get; set; }
}
If you are concerned giving yourself more work when you regenerate the code at some point in the future, then I recommend you write a PowerShell script to do this transformation automatically. After all svcutil is just a script written by some guy at Microsoft. It is not magic or "correct" or "standard". Your script can make a call to scvutil and then make a few quick changes to the resulting file.
EDIT (After seeing your edit)
You are already using MessageBodyMemberAttribute's Name property so just change this:
public string SimpleRequest1;
To
public string Request1;
Do you actually need these classes to have a common interface? I'd be tempted to instead create a wrapper interface (or just a concrete class) which could then use reflection to access the fields in question:
// TODO: Make this class implement an appropriate new interface if you want
// to, for mocking purposes.
public sealed class RequestWrapper<TRequest, TMessage>
{
private static readonly FieldInfo headerField;
private static readonly FieldInfo messageField;
static RequestWrapper()
{
// TODO: Validation
headerField = typeof(TRequest).GetField("Header");
messageField = typeof(TRequest).GetField(typeof(TRequest).Name + "1");
}
private readonly TRequest;
public RequestWrapper(TRequest request)
{
this.request = request;
}
public string Header
{
get { return (string) headerField.GetValue(request); }
set { headerField.SetValue(request, value); }
}
public TMessage Message
{
get { return (TMessage) messageField.GetValue(request); }
get { messageField.SetValue(request, value); }
}
}
You could use expression trees to build delegates for this if the reflection proves too slow, but I'd stick to a simple solution to start with.
The advantage of this is that you only need to write this code once - but it does mean creating a wrapper around the real request objects, which the partial class answers don't.

virtual properties

I have used and learned only virtual methods of the base class without any knowledge of virtual properties used as
class A
{
public virtual ICollection<B> prop{get;set;}
}
Could someone tell me what that means ?
public virtual ICollection<B> Prop { get; set; }
Translates almost directly to:
private ICollection<B> m_Prop;
public virtual ICollection<B> get_Prop()
{
return m_Prop;
}
public virtual void set_Prop(ICollection<B> value)
{
m_Prop = value;
}
Thus, the virtual keyword allows you to override the property in sub-classes just as you would the above get/set methods:
public override ICollection<B> Prop
{
get { return null; }
set { }
}
In object-oriented programming, a virtual property is a property whose behavior can be overridden within an inheriting class. This concept is an important part of the polymorphism portion of object-oriented programming (OOP).
look at the example below:
public class BaseClass
{
public int Id { get; set; }
public virtual string Name { get; set; }
}
public class DerivedClass : BaseClass
{
public override string Name
{
get
{
return base.Name;
}
set
{
base.Name = "test";
}
}
}
at the presentation level:
DerivedClass instance = new DerivedClass() { Id = 2, Name = "behnoud" };
Console.WriteLine(instance.Name);
Console.ReadKey();
the output will be "test", and not "behnoud", because the "Name" property has been overridden in the derived class(sub class).
In Entity Framework (which I believe your example refers to), your POCO classes are created and wrapped into a proxy class. Proxy class is a descendant of the class that you declare, so your class A becomes a base class. This proxy class is populated with data and returned back to you. This is necessary in order to track changes. Have a look at this article http://technet.microsoft.com/en-us/query/dd456848
I had a similar problem in trying to understand this and after a few debugging sessions and seeing the proxy classes and reading about tracking changes it made be figure out why it is declared the way it is.
Properties are actually specials cases of Getter and Setter methods. So they are like combinations of Getter and Setter methods as shown below:
private string _name;
public string GetName()
{
return _name;
}
public void SetName(string value)
{
this._name = value;
}
So virtual keyword is same for properties as well which means it is overrideable by the child classes and initial implementation can be changed.
Properties are a shortened form of accessor methods (Get & Set). That means that the virtual keyword has the same meaning as with any other method. That means you can override it in derived classes.
You can have methods (often), properties, indexers or events, the virtual keyword has the same meaning : modifying the meaning (override) of the base class item.
With properties, you can change the get/set accessors.
It's a collection that's implementation can vary in a descendant class.

Creating read-only versions of classes in a complex object structure

In my current project I need to be able to have both editable and read-only versions of classes. So that when the classes are displayed in a List or PropertGrid the user is not able to edit objects they should not be allowed to.
To do this I'm following the design pattern shown in the diagram below. I start with a read-only interface (IWidget), and then create an edtiable class which implements this interface (Widget). Next I create a read-only class (ReadOnlyWidget) which simply wraps the mutable class and also implements the read only interface.
I'm following this pattern for a number of different unrelated types. But now I want to add a search function to my program, which can generate results that include any variety of types including both mutable and immutable versions. So now I want to add another set of interfaces (IItem, IMutableItem) that define properties which apply to all types. So IItem defines a set of generic immutable properties, and IMutableItem defines the same properties but editable. In the end a search will return a collection of IItems, which can then later be cast to more specific types if needed.
Yet, I'm not sure if I'm setting up the relationships to IMutable and IItem correctly. Right now I have each of the interfaces (IWidget, IDooHickey) inheriting from IItem, and then the mutable classes (Widget, DooHickey) in addition also implement IMutableItem.
Alternatively, I was also thinking I could then set IMutableItem to inherit from IItem, which would hide its read-only properties with new properties that have both get and set accessors. Then the mutable classes would implement IMutableItem, and the read-only classes would implement IItem.
I'd appreciate any suggestions or criticisms regarding any of this.
Class Diagram
Code
public interface IItem
{
string ItemName { get; }
}
public interface IMutableItem
{
string ItemName { get; set; }
}
public interface IWidget:IItem
{
void Wiggle();
}
public abstract class Widget : IWidget, IMutableItem
{
public string ItemName
{
get;
set;
}
public void Wiggle()
{
//wiggle a little
}
}
public class ReadOnlyWidget : IWidget
{
private Widget _widget;
public ReadOnlyWidget(Widget widget)
{
this._widget = widget;
}
public void Wiggle()
{
_widget.Wiggle();
}
public string ItemName
{
get {return _widget.ItemName; }
}
}
public interface IDoohickey:IItem
{
void DoSomthing();
}
public abstract class Doohickey : IDoohickey, IMutableItem
{
public void DoSomthing()
{
//work it, work it
}
public string ItemName
{
get;
set;
}
}
public class ReadOnlyDoohickey : IDoohickey
{
private Doohickey _doohicky;
public ReadOnlyDoohickey(Doohickey doohicky)
{
this._doohicky = doohicky;
}
public string ItemName
{
get { return _doohicky.ItemName; }
}
public void DoSomthing()
{
this._doohicky.DoSomthing();
}
}
Is it OK to create another object when you need a readonly copy? If so then you can use the technique in the included code. If not, I think a wrapper is probably your best bet when it comes to this.
internal class Test
{
private int _id;
public virtual int ID
{
get
{
return _id;
}
set
{
if (ReadOnly)
{
throw new InvalidOperationException("Cannot set properties on a readonly instance.");
}
}
}
private string _name;
public virtual string Name
{
get
{
return _name;
}
set
{
if (ReadOnly)
{
throw new InvalidOperationException("Cannot set properties on a readonly instance.");
}
}
}
public bool ReadOnly { get; private set; }
public Test(int id = -1, string name = null)
: this(id, name, false)
{ }
private Test(int id, string name, bool readOnly)
{
ID = id;
Name = name;
ReadOnly = readOnly;
}
public Test AsReadOnly()
{
return new Test(ID, Name, true);
}
}
I would suggest that for each main class or interface, there be three defined classes: a "readable" class, a "changeable" class, and an "immutable" class. Only the "changeable" or "immutable" classes should exist as concrete types; they should both derive from an abstract "readable" class. Code which wants to store an object secure in the knowledge that it never changes should store the "immutable" class; code that wants to edit an object should use the "changeable" class. Code which isn't going to write to something but doesn't care if it holds the same value forever can accept objects of the "readable" base type.
The readable version should include public abstract methods AsChangeable(), AsImmutable(), public virtual method AsNewChangeable(), and protected virtual method AsNewImmutable(). The "changeable" classes should define AsChangeable() to return this, and AsImmutable to return AsNewImmutable(). The "immutable" classes should define AsChangeable() to return AsNewChangeable() and AsImmutable() to return this.
The biggest difficulty with all this is that inheritance doesn't work terribly well if one tries to use class types rather than interfaces. For example, if one would like to have an EnhancedCustomer class which inherits from BasicCustomer, then ImmutableEnhancedCustomer should inherit from both ImmutableBasicCustomer and ReadableEnhancedCustomer, but .net doesn't allow such dual inheritance. One could use an interface IImmutableEnhancedCustomer rather than a class, but some people would consider an 'immutable interace' to be a bit of a smell since there's no way a module that defines an interface in such a way that outsiders can use it without also allowing outsiders to define their own implementations.
Abandon hope all ye who enter here!!!
I suspect that in the long run your code is going to be very confusing. Your class diagram suggests that all properties are editable (or not) in a given object. Or are your (I'm)mutable interfaces introducing new properties that are all immutable or not, separate from the "core"/inheriting class?
Either way I think you're going to end up with playing games with property name variations and/or hiding inherited properties
Marker Interfaces Perhaps?
Consider making all properties in your classes mutable. Then implement IMutable (I don't like the name IItem) and IImutable as a marker interfaces. That is, there is literally nothing defined in the interface body. But it allows client code to handle the objects as a IImutable reference, for example.
This implies that either (a) your client code plays nice and respects it's mutability, or (b) all your objects are wrapped by a "controller" class that enforces the given object's mutability.
Could be too late :-), but the cause "The keyword 'new' is required on property because it hides property ..." is a bug in Resharper, no problem with the compiler. See the example below:
public interface IEntityReadOnly
{
int Prop { get; }
}
public interface IEntity : IEntityReadOnly
{
int Prop { set; }
}
public class Entity : IEntity
{
public int Prop { get; set; }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var entity = new Entity();
(entity as IEntity).Prop = 2;
Assert.AreEqual(2, (entity as IEntityReadOnly).Prop);
}
}
Same for the case without interfaces. The only limitation, you can't use auto-properties
public class User
{
public User(string userName)
{
this.userName = userName;
}
protected string userName;
public string UserName { get { return userName; } }
}
public class UserUpdatable : User
{
public UserUpdatable()
: base(null)
{
}
public string UserName { set { userName = value; } }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var user = new UserUpdatable {UserName = "George"};
Assert.AreEqual("George", (user as User).UserName);
}
}

How to force a derived class to include certain properties with default value

I have a class structure for a role playing game which looks like this...
public abstract class Item
{
public abstract string Name { get; set; }
}
public abstract class Armor : Item
{
public override string Name { get; set; }
}
public class Helmet : Armor
{
public override string Name { get; set; }
}
Basically, I am trying to force every derived type to include a "Name" property. Is this the best way to do it? I know I can remove "abstract" from Item.Name and then remove the overriden "Name" properties in Armor and Helmet. If I do that the code looks a little cleaner but I might forget to set the base.Name in these derived classes.
Could someone help show me the best way to do this?
EDIT:
Sorry, let me clarify my question a little more. I want to make sure of 2 things.
1) Name property exists in all derived classes
2) Name property is not null or empty
I basically want to force any class that derives from Item (and is not abstract) to have a value for Name.
It sounds like you are worried about initialising properties?
but I might forget to set the
base.Name in these derived classes.
One way the you can force the Name property to be set is to include this setter in your base class constructor like so:
public class MyBaseClass
{
private string _name;
public MyBaseClass(string name)
{
_name = name;
}
}
Then everything that derives from MyBaseClass must satisfy that constructor:
public class MyDerivedClass
{
public MyDerivedClass(string name) : base(name)
{
}
}
Then you can also make the property either:
abstract to ensure that it exists in each derived class with its own implementation
virtual to provide a base implementation and all it to be overridden.
I'm not going to venture whether the above is good design, but it would work to ensure that all derived classes have a valid name property when instantiated.
Another approach, as other answers suggest, is to implement a virtual property that throws an exception in its base implementation.
You only need to define Name in the base class, and do not need to specify it as abstract. It will still be available as a property in all derived classes.
public abstract class Item
{
public string Name { get; set; }
}
public abstract class Armor : Item
{ }
public class Helmet : Armor
{ }
If I do that the code looks a little cleaner but I might forget to set the base.Name in these derived classes.
Then the name of the object will just end up being something silly.
Better yet, have name start out as null. Then you'll get an exception if you forget to initialize the name but someone tries to use it, and you'll know you have to fix it.
Mike is right that if you just want to use the property "Name" on all derived objects, you don't need it to be marked abstract at all as it's inherited.
If you want to just force the fact that when Items are created, a name is definitely set, you could force it through hiding the zero-parameter constructor and exposing a constructor that accepts the name.
Take a look at this code:
public class Item
{
public string Name { get; set; }
public Item(string name)
{
this.Name = name;
}
protected Item() {}
}
public class Armor : Item
{
public Armor(string name) : base(name) {}
protected Armor() {}
}
public class Helmet : Armor
{
public Helmet(string name) : base(name) {}
protected Helmet() {}
}
The above definitions mean that:
Helmet myHelmet = new Helmet(); //will not build
Helmet myHelmet = new Helmet("Some Fancy Helmet Name"); //will build
Armor myArmor = new Armor (); //will not build
Armor myArmor = new Armor ("Some Fancy Armor Name"); //will build
Item myItem = new Item (); //will not build
Item myItem = new Item("Some Fancy Item Name"); //will build
This forces that any instance of the classes must define the name at time of creation. One possible solution anyway...
Would making Name a virtual ie. public virtual Name {get; set; } accessor be used in the Item class? Since Helment and Armor descend from the Item class. It would enforce that they must be overridden...
Hope this helps,
Best regards,
Tom.
so it depends what you want to do ...
making class abstract forces all the sub-classes to implement the class (and its abstract functions, etc.), but if you want a function to have a base functionality with the possibility to override the function then i'll suggest not making the class abstract and making the specific function virtual instead, thus when the virtual function is not being overwritten, and base function will be called.
and there's always options to create a "new" properties with the same name, but i don't think that's a good practice.
hope that helps.
i think you can still make the property virtual within a abstract class, thus that should solve your problem.
You can set the value to something specific in the base abstract class,
here an example :
public abstract class Item
{
public virtual string Name
{
get {return m_strName;}
set {m_strName = value;}
}
public abstract class Armor : Item
{
public override string Name { get; set; } // if you want to override it
}
public class Helmet : Armor
{
public override string Name { get; set; } // if you want to override it
}

Categories