I have a base class with an attribute and I want to hide it in a derived class. Is there any way to do this other than using reflection?
[Authorize(Roles = "User,Admin,Customs")]
public abstract class ApplicationController : Controller
{
}
// hide the Authorize attribute
public class ErrorController : ApplicationController
{
}
You could override the AuthorizeAttribute with your own class and specify it to not be inherited.
[AttributeUsage(AttributeTargets.Class, Inherited=false)]
public class NonInheritedAuthorizeAttribute : AuthorizeAttribute
{
// Constructors, etc.
}
Now you can specify which class to use, as long as you own ApplicationController.
Removing features inherited from a base class violates the Liskov Substitution Principle. Breaking inheritance in this way usually rears its ugly head with unintended and unexpected consequences—after it's too late to change the root problem.
So even if there is a way, I'll answer that you shouldn't use it the vast majority of the time. Alternatives to inheritance may apply, such as containment (has-a instead of inheritance's is-a) or refactoring the base into a separate interface which both can then implement; or even combine both of these.
If it was a method/prop, you could re-declare (new) the member without the offending attribute. I don't know of a way with class-level attributes.
public new SomeType Foo() { return base.Foo(); }
Depends a bit on what you mean by 'Hide'. You should be able to revoke the authorization like this:
// hide the Authorize attribute
[Authorize(Roles = "")]
public class ErrorController : ApplicationController
{
}
You can specify the 'AttributeUage' attribute on your Attribute class, like this:
[AttributeUsage(AttributeTargets.Class, Inherited=false)]
public class AuthorizeAttribute : Attribute
{
}
Then, classes that derive from the class where you've applied the attribute, will not inherit the attribute.
Ow, now I realize that the Authorize attribute is not a custom attribute.
Related
In order to decorate a class with AttributeUsage, the decorated class must also inherit from Attribute.
Can I enforce a similar constraint with a custom attribute?
The AttributeUsageAttribute is apparently a core feature of the language, so this restriction is mandated by the C# specification:
A class that is decorated with the AttributeUsage attribute must derive from System.Attribute, either directly or indirectly. Otherwise, a compile-time error occurs.
That means there's no straightforward way of achieving such a restriction. You can write a custom static analyzer to throw warnings at erroneous usage, or see Anton Anpilogov's answer for a workaround.
The only way to do that is to use protected attribute, but in that case, you'll force users of your attribute to inherit from your attribute class.
abstract class CustomAttribute : Attribute {
[AttributeUsage(AttributeTargets.Class)]
protected sealed class MyTestAttribute : Attribute {}
}
[MyTest]
class DerivedFromYourCustomAttribute : CustomAttribute {
}
[MyTest]
class NotDerivedFromYourCustomAttribute {
}
I'd like to have some common logic shared between two screens, so I want to have an abstract class inheriting from PXGraph, and then two different Graphs inheriting from this abstract class.
Like this :
namespace LE
{
public abstract class ICarrySomeLogic : PXGraph<ICarrySomeLogic>
{
// common business logic
}
public class graph1 : ICarrySomeLogic
{
// specific business logic
}
public class graph2 : ICarrySomeLogic
{
// specific business logic
}
}
Does it work correctly ? Is there a "best practice" or another proper way to do it ?
Thanks a lot,
I have done this before and works great. Here is my example simplified...
public abstract class MyGraphBase<TGraph, TPrimary, TWhere> : PXGraph<TGraph, TPrimary>
where TGraph : PXGraph
where TPrimary : class, IBqlTable, new()
where TWhere : class, IBqlWhere, new()
{
public PXSelect<TPrimary, TWhere> document;
}
public class GraphOneEntry : MyGraphBase<GraphOneEntry, MyDac, Where<MyDac.docType, Equal<DocType.typeOne>>>
{
}
public class GraphTwoEntry : MyGraphBase<GraphTwoEntry, MyDac, Where<MyDac.docType, Equal<DocType.typeTwo>>>
{
}
My events in the base abstract class will fire and I can override as needed in the other graphs.
I have been using this since version 5.3
Edit: starting in 2017R2 there is a new concept around Reusable Business Logic that can also be utilized for this same purpose.
The example you have given should do what you need. The inheritable traits and behavior of your abstract class will be inherited by your subclasses as expected. This works for extension classes as well. If you extend an existing Graph, you can then subclass your extension class to achieve inheritance.
Note: The "I" prefix for type naming is a standard in C# for interfaces, not classes. Even though abstract classes have some similarities to interfaces, they are not the same. If you want to follow Microsoft best practices, you might consider not using this prefix for class naming. If your I prefix is simply meant as the word "I" (as in you, yourself), then you can just ignore this note. :)
I have following easy class design, where myObject is importing for BaseClass.
public abstract class BaseClass
{
public BaseClass(myObject parameter)
{
// ...
}
}
public class ChildClass : BaseClass
{
}
My problem is now, that I want to make my program extensible by inheriting from public BaseClass. So you could create a constructor
public ChildClass() :base(new myObject()){...}
which will lead to failures. Is there a possibilty to prevent inherited classes with own constructors? I actually would like to avoid constructors for ChildClass at all. Is this possible? Then I could use a factory and provide an Initialize method. Or is this something impossible, where I simply must be aware of and check in my code=
Classes are completely responsible for their own constructors. They aren't inherited, and every class must have a constructor. So no, there's nothing you can do to "control" what constructors a base class can or can't have.
An interface is sort of like a contract which when it's implemented within a class you are guaranteed that this class has a set of specific public methods that you can call.
I was wondering how I could use this principle for attributes ; i.e. having a interface which when a class implements it I'm guaranteed that this class has a set of specific attributes.
I am looking for this feature because I am using Protobuf and this library requires the classes you want to serialize have a specific attribute (XmlType for instance, but other similar attributes work too). I would like to manipulate a set of objects whatever their type is as long as they have this specific attribute.
I don't see how you can do that with interfaces.
However, you can do it with an abstract class which has methods with the attributes you want.
These methods will call abstracts methods which then must be implemented.
For example:
public abstract class A
{
[XmlType]
public void F()
{
InnerF();
}
protected abstract InnerF();
}
public class B extends A
{
protected void InnerF()
{
}
}
Another option ofcourse, is running a post build tool that will validate your code for rules you define.
Take a look here
I'm reading Pro C# 2010 and the .Net 4 Platform by Andrew Troelsen.
In Chapter 15 about Attributes exists a note:
Note: For security reasons, it is considered a .Net best practice to design all custom attributes as sealed.
The author doesn't explain why, can someone explain why?
CA1813: Avoid unsealed attributes:
The .NET Framework class library provides methods for retrieving
custom attributes. By default, these methods search the attribute
inheritance hierarchy; for example Attribute.GetCustomAttribute
searches for the specified attribute type, or any attribute type that
extends the specified attribute type. Sealing the attribute eliminates
the search through the inheritance hierarchy, and can improve
performance.
Ref: https://learn.microsoft.com/visualstudio/code-quality/ca1813-avoid-unsealed-attributes
Attributes are simply metadata discovered at runtime. As it is quoted, if someone else derives from your custom attribute class, by default .NET will find them too, which may imply a security risk if the derived attribute class is modifying the behavior of your original attribute in a way to you never intended to.
Even though performance is the prime reason to seal attribute classes, here is a formidable article dealing with its security side.
There is one more reason to seal attributes.
Consider the following attribute:
[AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = false)]
public class Attr1 : Attribute
{
}
Here you allow only single attribute decoration: AllowMultiple = false
Compiler won't allow this:
[Attr1]
[Attr1]
public class Foo
{
}
Later in your code you can safely call memberInfo.GetCustomAttribute() which will throw AmbiguousMatchException if more then one attribute of the given type was found.
Let's now inherit:
public class Attr2 : Attr1
{
}
Now compiler is silent.
[Attr1]
[Attr2]
public class Foo
{
}
So if later somebody inherits from your attribute and passes back to your code some entity marked with both attributes unexpected exception will be thrown.
Full example:
class Program
{
static void Main(params string[] args)
{
typeof(Foo).GetCustomAttribute<Attr1>();
}
[AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class Attr1 : Attribute
{
}
public class Attr2 : Attr1
{
}
[Attr1]
[Attr2]
public class Foo
{
}
[Attr1]
public class Bar : Foo
{
}
}
Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries just says:
DO seal custom attribute classes, if possible. This makes the look-up for the attribute faster.
I didn't see anything about security in that section, but #Teoman Soygul makes a good point. So I'd agree with Mr. Troelsen.