Why does my re-implemented method retain the base class' attribute? - c#

I have two classes, RichString and RequiredRichString. In RequiredRichString, I'm re-implementing the Value property with the 'new' keyword. If I reflect the attributes on Value on RequiredRichString, I only get Required, but after testing posting markup multiple times, AllowHtml is still taking effect.
public class RichString
{
[AllowHtml]
public string Value { get; set; }
}
public class RequiredRichString : RichString
{
[Required]
new public string Value { get; set; }
}
In short: Why does ASP.NET still acknowledge the AllowHtml attribute when I re-implement the Value property with new?

If you have the flag set:
[AttributeUsage(Inherited=true)]
Then the attribute will be inherited.
But you can subclass the Attribute to your needs, ie MyAttribute(Enabled = true) in the base class and MyAttribute(Enabled = false) in the new implementation. For instance...
[AttributeUsage(Inherited=true, AllowMultiple=true, Inherited=true)]
public class MyAttribute : Attribute
{
public bool Enabled { get; set; }
public MyAttribute() { }
public void SomethingTheAttributeDoes()
{
if (this.Enabled) this._DoIt)();
}
}
public class MyObject
{
[MyAttribute(Enabled = true)]
public double SizeOfIndexFinger { get; set; }
}
public class ExtendedObject : MyObject
{
[MyAttribute(Enabled = false)]
public new double SizeOfIndexFinger { get; set; }
}
Note this answer: How to hide an inherited property in a class without modifying the inherited class (base class)? - it seems maybe you can achieve what you want by using method overriding rather than hiding.
I can understand why you would think otherwise for a new property, but my understanding is that new is about providing a new implementation, often in the form of a new storage mechanism (a new backing field for instance) rather than changing the visible interface of the subclass. Inherited=true is a promise that subclasses will inherit the Attribute. It makes sense or at least it could be argued that only a superseding Attribute should be able to break this promise.

Related

Get value from inheritance out of a collection

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.

Override Getter/Setter with Custom Attribute

We have a custom ConfigurationManager library that serializes/deserializes a config.json file into an ExpandoObject.
Would it be possible to create a custom attribute that overrides the Getter/Setter of these properties to abstract this ExpandoObject?
Ideally I would be able to use the Attribute like this:
[System.AttributeUsage(System.AttributeTargets.Property)]
class Configureable : System.Attribute
{
public string Default { get; set; }
public bool IsEncrypted { get; set; }
}
class Test
{
[Configureable(Default = "0",IsEncrypted = false)]
public string MyValue { get; set; }
}
When I set the value of the decorated property I want to auto-magically update the value of the ExpandoObject, which would then in turn force an update be written to my config.json file.
When I access the value of the decorated property I want the getter to actually return the value of the underlying ExpandoObject. I can do this by manually having the developer modify the getter/setter. I was wondering if I could also do this with code inside of the attribute.
Thank you!
I found http://doc.postsharp.net/location-interception
That seems to do exactly what I want.
[System.AttributeUsage(System.AttributeTargets.Property)]
[Serializable]
class Configureable : LocationInterceptionAspect
{
public string Default { get; set; }
public bool IsEncrypted { get; set; }
public override void OnGetValue(LocationInterceptionArgs args)
{
base.OnGetValue(args);
if (args.Value == null)
{
}
}
public override void OnSetValue(LocationInterceptionArgs args)
{
//base.OnSetValue(args);
}
}
class Test
{
[Configureable(Default = "0",IsEncrypted = false)]
public string MyValue { get; set; }
}
ExpandoObject is a dictionary with object syntax. It is useful only in simple scenarios. If you need complex logic, use DynamicObject intead. Override its TryGetMember and TrySetMember methods to replicate functionality of ExpandoObject, then customize logic of these methods in the way you want.
It's not clear what your requirements are though. If you have a class which holds properties, what is the point of having dynamic objects?

Implementing interfaces in C# .NET

Consider the following interface
public interface ICustomData
{
String CustomData { set; get; }
}
According to MSDN documentation, interfaces members are automatically public.
Lets say I now want to implement my interface:
public class CustomDataHandler : ICustomData
{
}
This would break at compile time, telling me that I have not implemented "CustomData"
This on the otherhand would work:
public class CustomDataHandler : ICustomData
{
public String CustomData { set; get; }
}
My question is: If the member of the interface is automatically public, why MUST I declare the implementation in the class? If the interface declaration is syntactically identical to the class declaration, why can the compiler not infer this automatically from my interface?
EDIT:
My reason for asking. Imagine a scenario where you are building data models, entities etc. I might code some interfaces to these models like so:
public interface IUserAccount
{
Guid Identity { set; get; }
String FirstName { set; get; }
String LastName { set; get; }
String EmailAddress { set; get; }
String Password { set; get; }
}
public interface IUserDataEntry
{
Guid DataIdentity { set; get; }
String DataName { set; get; }
String Data { set; get; }
}
It would be far simpler to construct the models like so:
public class UserAccount : IUserAccount
{
}
public class UserDataEntry : IUserDataEntry
{
}
public class Combined : IUserAccount, IUserDataEntry
{
}
An interface is not there to provide an implementation, it is there to define a contract. This then allows for different implementations to be built which implement it.
They may be syntactically identical, but they mean different things (i.e. they are not semantically identical).
In the interface, the syntax means that an implementing class must expose such a property, with get and set accessors implemented as it sees fit (either explicitly or implicitly). An interface merely defines the outward behaviour that a class must provide; it does not provide any implementation of that behaviour.
In the class, the syntax is an "auto-property", an implementation of the property defined by the interface, and the get and set accessors are implicitly converted into full implementations with a backing field. It looks something like this when it's compiled:
public class CustomDataHandler : ICustomData
{
private string customData;
public string CustomData
{
get
{
return customData;
}
set
{
customData = value;
}
}
}
You are implicitly implementing the interface. In this instance the method signatures of the class must match those of the interface (including accessibility). Ensuring that the methods are marked as public ensures that there are no surprises when looking at the class, for instance:
public class CustomDataHandler : ICustomData
{
String CustomData {get; set}
String PrivateCustomData {get;set;}
}
Even though both properties are declared the same, the CustomData property would be public by virtue of it being declared on the interface even though the declaration looks identical to that of PrivateCustomData. This would be inconsistent and lead to harder to maintain code.
If you do not wish to set the access modifier, you could explicitly implement the interface:
public class CustomDataHandler : ICustomData
{
String ICustomData.CustomData { set; get; }
}
The interface declaration is only specifying the behaviour which the interface defines. In your case, this is a property called CustomData which has a get and set (it is a read/write property) which is of type string.
The class which implements the interface needs to do exactly that - to specify the implementation.
Now in your case, you are using auto implemented properties { get; set; } which looks the same as the interface declaration, however you could also have a backing field and behaviour in your get or set methods.
Here's an example where the CustomData property is private in a derived class:
public class CustomDataHandler : ICustomData
{
private string CustomData { set; get; }
string ICustomData.CustomData { get; set; }
}
But this code compiles, because there is also an explicit implementation of the property.
So, the public modifier is not redundant in this case.
You must explicitly implement it because... You are not limited to implementing it that way. You could use a field, or do something else in your method. An interface is only a method contract that guaranty that this method exist.
public class CustomDataHandler : ICustomData
{
public String CustomData
{
get { return "None of your business!"; }
set { } // Decide to do nothing
}
}
The interface only guaranty this method will exist. Not what you're gonna do with it.
EDIT: As for your edit of your question, you probably seek to have a parent class instead of an interface if you want to implement the method only once for a collection of classes. However, while you can combine interface, you cannot combine parent classes. But, you can add interface at different point of a classes hierarchy.

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.

How to specify one property is attribute of another In C# XML serialization?

I want to specify that one property in an XML serializable class is an attribute of another property in the class, not of the class itself. Is this possible without creating additional classes?
For example, if I have the following C# class
class Alerts
{
[XmlElement("AlertOne")]
public int AlertOneParameter { get; set; }
public bool IsAlertOneEnabled { get; set; }
}
how can I specify that IsAlertOneEnabled is an attribute of AlertOne so that the XML serializes to the following?
<Alerts>
<AlertOne Enabled="True">99</AlertOne>
</Alerts>
If you are using XmlSerializer with default (non-IXmlSerializable) serialization, then indeed: this cannot be achieved without adding an extra class that is the AlertOne, with an attribute and a [XmlText] value.
If you implement IXmlSerializable it should be possible, but that is not a nice interface to implement robustly (the deserialization, in particular, is hard; if it is write-only then this should be fine). Personally I'd recommend mapping to a DTO model with the aforementioned extra class.
Other tools like LINQ-to-XML would make it pretty simple, of course, but work differently.
An example of a suitable DTO layout:
public class Alerts
{
[XmlElement("AlertOne")]
public Alert AlertOne { get; set; }
}
public class Alert
{
[XmlText]
public int Parameter { get; set; }
[XmlAttribute("Enabled")]
public bool Enabled { get; set; }
}
You could of course add a few [XmlIgnore] pass-thru members that talk to the inner instance.

Categories