Hola.
Primero de nada debemos aclarar que, hablando con propiedad de la palabra, un atributo de clase no es a lo que te refieres, sería esto otro:
[ClassAtttibute()]
public class Class1 { }
...A lo que tú te refieres es a un campo o variable, en este caso.
Esta es la única forma de hacerlo, pero claro, esto significa que si quiero acceder desde fuera voy a tener que jartarme a metodos o a propiedades en este caso, y es un poco coñazo
...¿Qué?. No se te entiende nada. En el ejemplo que has puesto, la variable "cagonto" tiene un acceso privado, por ende solo es accesible a nivel de clase (la clase donde fue declarada esa variable), no es accesible desde ningún otro lugar como la clase "Hola" de tu ejemplo (a menos que utilices Reflection), lo cual es correcto, ya que no tendría sentido que fuese de otra manera.
Hacer que el atributo de una clase no se pueda heredar y que al mismo tiempo sea accesible desde otras clases
No, así no es como trabaja la herencia, y no sería buena idea, y además iría en contra de los principios de la organización según mi opinión. En lugar de intentar prohibir la herencia, cosa que no puedes como lo quieres hacer, puedes considerar la idea de ocultar el miembro mediante los atributos
DesignerSerializationVisibility,
Browsable, y
EditorBrowsable (según tus necesidades), pero a partir de la versión 2015 o 2017 de Visual Studio la aplicación de esos atributos no tendrá ningún efecto si estás trabajando directamente sobre el código fuente (es decir, los miembros no se ocultarán en tu código fuente, se ocultarían si trabajas con la clase/dll/exe compilada en un proyecto diferente que no sea el código fuente donde declaraste esos miembros, espero que se me entienda).
Lo que yo hago con miembros base que deben ser heredados obligatoriamente pero no necesitan ser consumidos y/o implementados por las clases derivadas (aunque siempre se pueden reimplementar y/o acceder a los miembros base si lo deseamos, así que no supone ningún impedimento), entonces los oculto en el editor de código y así me aseguro de que no se produce ningún fallo humano/intento de acceder a un miembro heredado de forma
involuntaria (puesto que como ya digo, de forma voluntaria se puede acceder a ellos, solo que están ocultos, y eso siempre es un buen indicativo de que no se deberían usar...)
Te muestro un ejemplo sacado de mi framework de pago
ElektroKit:
// ***********************************************************************
// Author : Elektro
// Modified : 25-June-2016
// ***********************************************************************
#region " Imports "
using System.ComponentModel;
#endregion
#region " Aesthetic Object "
namespace Types {
/// ----------------------------------------------------------------------------------------------------
/// <summary>
/// This is a class to consume for aesthetic purposes.
/// <para></para>
/// A default (emptyness) class that inherits from <see cref="Object"/>, with these base members hidden:
/// <para></para>
/// <see cref="System.Object.GetHashCode"/>, <see cref="System.Object.GetType"/>,
/// <see cref="System.Object.Equals(Object)"/>, <see cref="System.Object.Equals(Object, Object)"/>,
/// <see cref="System.Object.ReferenceEquals(Object, Object)"/>, <see cref="System.Object.ToString()"/>.
/// </summary>
/// ----------------------------------------------------------------------------------------------------
public abstract class AestheticObject : object
{
#region " Hidden Base Members (of Object) "
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual new int GetHashCode
() { return base.GetHashCode();
}
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual new Type GetType
() { return base.GetType();
}
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual new bool Equals
(object obj
) { return base.Equals(obj);
}
[EditorBrowsable(EditorBrowsableState.Never)]
public static new bool Equals
(object objA,
object objB
) { return object.Equals(objA, objB);
}
[EditorBrowsable(EditorBrowsableState.Never)]
public static new bool ReferenceEquals
(object objA,
object objB
) { return object.ReferenceEquals(objA, objB);
}
[EditorBrowsable(EditorBrowsableState.Never)]
public override string ToString() {
return base.ToString();
}
#endregion
}
}
#endregion
Código original y documentado:
AestheticObject.vbAparte, tampoco es una buena idea que declares una variable de tipo "Object" en una clase heredable si lo que te importa es ser eficiente y organizado, en su lugar puedes trabajar con una clase genérica y así asegurar que el tipo del objeto será reconocible en tiempo de ejecución:
public class GenericClass<T> {
public readonly T Obj;
private GenericClass() { }
public GenericClass(T type) {
this.Obj = type;
}
}
public sealed class InheritedClass : GenericClass<Color> {
public InheritedClass(Color value) : base(value) { }
}
GenericClass instance
= new GenericClass
(Color
.Red);Debug.WriteLine(instance.Obj.GetType().FullName);
O bien esto otro (lo que viene a ser lo mismo, pero para distinto uso):
public sealed class GenericClass<T> {
public readonly T Obj;
public GenericClass(T obj) {
this.Obj = obj;
}
}
GenericClass
<Color
> instance
= new GenericClass
<Color
>(Color
.Red);Debug.WriteLine(instance.Obj.GetType().FullName);
Saludos!