I'm try to find a solution to realize decrypt/encrypt when access a class property by get/set.
I had researched something about C# custom attribute, but seemimgly it can't work, so I want to know whether it's impossible to change the class property by attribute.
[AttributeUsage(AttributeTargets.Property)]
public class MyAttribute : Attribute
{
// How to change the tragetClass.Name when access by get/set
}
public class TargetClass
{
[MyAttribute]
public string Name { get; set; }
}
Related
Suppose we have created an attribute named [Mandatory]. Those exist any way to force a child class to have at least on field with this attribute while the parent class does not have any field??
For example suppose this:
class parent{
public abstract void doSomething(){};
}
What should I add to the parent class so child class had to be something like this:
class parent{
[Mandatory] public field1;
public override void doSomething(){ // do something ...};
}
And if it did not contain field1 it could not be compiled. Does exist something like this in c#?
Update
The parent class is only to apply a rule that Already staff respect but I wanted to guarantee that everybody have to declare at least on field. I think this is not a case of object oriented application. But I'm trying to force them obey this convention using oop! If it is not the correct way please inform me.
Thanks for any help.
Did you specifically want an abstract field or is a property sufficient?
How about the following?
abstract class Base
{
public abstract int Field { get; set; }
}
class Derived : Base
{
public override int Field { get; set; }
}
When I define an interface that contains a write-only property:
public interface IModuleScreenData
{
string Name { set; }
}
and attempt to (naively) implement it explicitly with an intention for the property to also have a publicly available getter:
public class ModuleScreen : IModuleScreenData
{
string IModuleScreenData.Name { get; set; }
}
then I get the following error:
Error 'IModuleScreenData.Name.get' adds an accessor not found in
interface member 'IModuleScreenData.Name'
The error is more or less expected, however, after this alternative syntax:
public class ModuleScreen : IModuleScreenData
{
public string Name { get; IModuleScreenData.set; }
}
has failed to compile, I suppose that what I am trying to do is not really possible. Am I right, or is there some secret sauce syntax after all?
You can do this:
public class ModuleScreen : IModuleScreenData
{
string IModuleScreenData.Name
{
set { Name = value; }
}
public string Name { get; private set; }
}
On a side note, I generally wouldn't recommend set-only properties. A method may work better to express the intention.
You can't change the how the interface is implemented in the inheriting class. That is the whole point.. if you need to do something new with a property you could make a new property that references the inherited properties specific implementation. Interfaces are there so you can conform to a specified standard for object inheritance.
UPDATE:
On second thought.. you should be able to just do this.... this will compile fine:
public class ModuleScreen : IModuleScreenData
{
public string Name { get; set; }
}
There's a fine question on overriding inherited attributes of properties.
Suppose an attribute:
[AttributeUsage(AttributeTargets.All, Inherited = true)]
public class MyAttributeAttribute : Attribute
//...
public class ParentClass
{
[MyAttribute]
public String MyString;
}
public class ChildClass : ParentClass
{
new public String MyString; //Doesn't have MyAttribute
}
But what if MyAttribute is set to a class?
[MyAttribute]
public class ParentClass
public class ChildClass; //Don't want MyAttribute
Is there a way to make ChildClass not inherit the attribute?
Context: Purely theoretical. I want to make an attribute inheritable and want to know, if the case happens some day, if I can override it.
You could copy the BrowsableAttribute approach mentioned in one of the answers to the question you reference. You can make a constructor with a boolean that when set to false will denote that the attribute, although present, should not be handled. You can also add a parameterless constructor that set the property to true. This is the one that you will use most often unless you decide to override the attribute inherited from a base class.
[AttributeUsage(AttributeTargets.All, Inherited = true)]
public class MyAttributeAttribute : Attribute
{
public bool Enabled { get; private set; }
public MyAttributeAttribute()
:this(true)
{
}
public MyAttributeAttribute(bool enabled)
{
Enabled = enabled;
}
}
Then when you reflect on your types and look for the attribute, you can check on the Enabled property and only if it is true you actually use it.
Your example class hierarchy will then be:
[MyAttribute]
public class ParentClass
[MyAttribute(false)]
public class ChildClass; //Don't want MyAttribute
Say I have the following set of classes, is it possible for the attributes of DerivedClass to be merged? Currently if I use the GetType().GetCustomAttributes()method passing in true for inheritance it takes the highest attributes in the inheritance structure.
i.e. [Another("Bob")] and [My(16)]
Is it possible for the attributes to be merged? So I would end up with two attributes of [My(16, "Male")] and [Another("Bob")]
I don't mean to say that I would specify an attribute of [My(16, "Male")] but rather I would be returned an attribute with an Age of 16 and a Gender of Male.
public class MyAttribute : Attribute
{
public MyAttribute(int age)
{
Age = age;
}
public MyAttribute(int age, string gender)
{
Age = age;
Gender = gender;
}
public int Age { get; set; }
public string Gender { get; set; }
}
public class AnotherAttribute : Attribute
{
public AnotherAttribute(string name)
{
Name = name;
}
public string Name { get; set; }
}
[My(12, "Male")]
[Another("Bob")]
public class BaseClass
{
}
[My(16)]
public class DerivedClass : BaseClass
{
}
You can have multiple instances of the same attribute on an entity (this is an option on the AttributeUsageAttribute applied to your attribute). When you get attributes on a type, you can get all the attributes applied to the inheritance chain.
However there is nothing in the standard tools that will take two attribute instances and make one.
(In theory a post processor that re-wrote the MSIL could do this.)
First, I don't believe any of the behavior you're inquiring about would depend on the AttributeUsage attribute which should be decorating your attribute classes (it looks like I could be wrong). Nor do I see where any attribute would be getting merged. Each attribute is a representation of a class in it's own right. Each attribute class should return it's own data. I would expect DerivedClass.GetCustomAttributes() to return three separate references for each attribute - 2 from the base class, and 1 for itself.
Try setting the AttributeUsage on the 'MyAttribute' to allow multiple. It may not be merging them, but taking the 'latest' version of the attribute.
I just thought of something else that could be causing the mysterious disappearing act. You may have to go after the base class to get the original attribute? You could try that:
base.GetType().GetCustomAttributes();
I did some digging and here is what the AttibuteUsage will do and could be causing you to only see one of the MyAttribute classes:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
I was close in my statement earlier about using AttributeUsage; however, it is the Inherited named parameter that will limit visibility to the base class' MyAttribute decoration. Try specifying Inherited = true and see what you get.
Given the following, I would not expect the compiler to allow multiple attributes that are derived from the base attribute, given that is set to AllowMultiple=false. In fact it compiles without a problem - what am I missing here?
using System;
[AttributeUsage(AttributeTargets.Property,AllowMultiple=false,Inherited=true)]
abstract class BaseAttribute : Attribute { }
sealed class DerivedAttributeA : BaseAttribute { }
sealed class DerivedAttributeB : BaseAttribute { }
class Sample1
{
[DerivedAttributeA()]
[DerivedAttributeB()]
public string PropertyA{ get; set; } // allowed, concrete classes differ
[DerivedAttributeA()]
[DerivedAttributeA()]
public string PropertyB { get; set; } // not allowed, concrete classes the same, honours AllowMultiple=false on BaseAttribute
}
The problem is simply that the AllowMultiple check only compares attributes of the same actual type (i.e. the concrete type instantiated) - and is perhaps best used with sealed attributes for this reason.
It will, for example, enforce the following (as an illegal duplicate), inheriting this from BaseAttribute:
[DerivedAttributeB()]
[DerivedAttributeB()]
public string Name { get; set; }
In short, I don't think you can do what you want here... (enforce no more than one instance including subclasses of BaseAttribute per property).
A similar example of this problem would be:
[Description("abc")]
[I18NDescriptionAttribute("abc")]
public string Name { get; set; }
class I18NDescriptionAttribute : DescriptionAttribute {
public I18NDescriptionAttribute(string resxKey) : base(resxKey) { }
}
The intent above is to provide a [Description] from resx at runtime (fully supported by ComponentModel etc) - but it can't stop you also adding a [Description].