Suppose I have a the following code:
Container.cs
public class Container
{
public readonly string IdType;
public Container( string aIdType )
{
IdType = aIdType;
}
}
SuperContainerA .cs
public class SuperContainerA : Container
{
public SuperContainerA( /*x parameters*/ ) : base("A") {}
}
SuperContainerB.cs
public class SuperContainerB : Container
{
public SuperContainerB( /*y parameters*/ ) : base("B") {}
}
SuperContainerToTheInfinityAndBeyond.cs
public class SuperContainerB : Container
{
public SuperContainerB( /*y parameters*/ ) : base("It's Over 9000!") {}
}
Based on that, what I'm trying to retrieve is the "A" and "B" that are being sent to the TypeId from the constructor.
The catch here is... I need to retrieve those values during the initialization of the program, before creating an instance of those classes, so I thought that using reflection is my best bet here. (Note: Creating an instance of the classes to retrieve the value would be valid if the number of parameters for each constructor would be the same, but they can change. :()
Is it possible to use reflection to check the literals of my source code and/or Assemblies? (If I can see something like the source code, then I can use Regex to get the value.)(Note: Including the sources as resource files to my program is not an option :P)
I'm thinking of declaring constants to hold the value and force an naming rule on then, so that I could use reflection later to grab then back. Something like ...
public class SuperContainerA
{
public const string ctIdType = "A";
}
public class SuperContainerB
{
public const string ctIdType = "B";
}
... But I'm not sure if this is the best approach to this problem, since I won't have anything to help me check if these consts have been declared and if they got the proper name during compile time.
Actually, if the language had some kind of static inheritance, this would help a lot in this situation, but I hear some programmers complaing that static inheritance is more of an head ache than a cure.
Anyway, I'm searching for alternatives. Any idea is welcome.
Attributes to the rescue!
public class IdTypeAttribute: Attribute
{
public string IdType { get; private set; }
public IdTypeAttribute(string idType)
{
IdType = idType;
}
}
[IdType("B")]
public class SuperContainerB: Container
{
// whatever you like...
}
You can then access the Attribute via reflection. Easy enough to do...
var type = typeof(SuperContainerB);
var attribute = (IdTypeAttribute)type.GetCustomAttributes(
typeof(IdTypeAttribute), false)[0];
var idType = attribute.IdType;
Why not simply use the concrete type to look up the string value that you seem to want associated with it?
public class SuperA : Container
{
public string IdType { get { return IdTypeFactory.Get( GetType() ); } }
}
public static class IdTypeFactory
{
public static string Get( Type containerType ) { ... }
}
The primary benefit of this solution would be to gather all your string literals in one central location. Alternatively, go with the abstract super class.
Related
Thanks ahead, community!
As the title describes, I would like to cast an object that is in parent type to a child type, which is actually a child type, whilst this 'specific type' cannot be known until runtime.
Lets say I have following data holder:
public class Holder {}
public class Holder<T> : Holder
{
public T Value;
}
And this Holder (not Holder<T>) will be given to some script at runtime.
I need to cast this Holder into Holder<T> (eg, Holder<string>), so that I can access the Value : T.
For now, I can just mannually add casting cases and their coresponding methods to process it, but time by time there will be more types that goes into this Holder<T>, and it would become imposible to manage in this way.
Is there a way to accomplish this objective?
This Holder must not be flattened, as it is being used in a context as below:
public class SomeNode
{
protected Holder holder;
}
public class SomeNode<T> : SomeNode
{
public SomeNode<T>()
{
holder = new Holder<T>();
}
}
I have no clue how to approach this, nor a search keyword to catch a hint about this.
Automatic suggestions came up before posting seems not my case, which were:
C# Create (or cast) objects of a specific type at runtime
C# Accessing generic Method without knowing specific type
Edit
Thanks to #W.F., I could start searching with an effective keyword 'dynamic object', and I ended up finding System.Reflection as my desired soultion.
It looks like as belows and currently it solves my immediate issue:
holder.GetType().GetProperty("GetValue").Invoke(holder, null);
But as pointed out by #OlivierJacot-Descombes, my structure and a way of using it is breaking a purpose of polymorphism. Therefore I still need a better solution, which would do a job I am looking for and also not breaking polymorphism.
Possible walkaround that comes in my head is that, first, create a method GetValue() in Holder, and also create class that inherits from Holder to implement this method:
public class Holder
{
public virtual string GetValue() => "";
}
public class Holder<T> : Holder
{
public T Value;
}
public class FloatHolder : Holder<float> //for example
{
public override string GetValue() => Value.ToString();
}
Second, change node structure like:
public class SomeNode
{
protected Holder holder;
}
public class SomeNode<T> : SomeNode {}
public class FloatNode : SomeNode<float>
{
public FloatNode()
{
holder = new FloatHolder();
}
}
Then, I can do like:
public class EchoNode : SomeNode
{
public void Tick()
{
Console.WriteLine(holder.GetValue());
}
}
Seems like too many classes are being created, but it also seems not breaking polymorphism.
Looking for further advices. Again, Thanks!
Edit#2
I already said this in the comment, but for better readability, I write this here as well.
Both Dynamic Object and System.Reflection were easy and fitting solutions which I was looking for, but they weren't best solutions in general.
At the beginning I was misinterpreting #OlivierJacot-Descombes 's answer. He was overall pointing out two impediments: first, my class structure is breaking polymorphism, and second, reflection is slow (and later I noticed, dynamic object as well). I didn't catch the last bit at first so I went through a long way.
Moreover, turned out, I couldn't use dynamic object for my project context, as I am not using normal C# but a Unity C#. Technically I can, but they don't blend well.
Thankfully, my revised solution was acceptable. Therefore I decided to select #OlivierJacot-Descombes 's post as an answer. But I hope, still, people would approach and leave me an good advices.
Thank you all.
If you need to cast to a specific type, you are doing polymorphism wrong. Of course you could do something like this:
switch (holder)
{
case Holder<string> stringHolder:
DoStringThing(stringHolder.Value);
break;
case Holder<int> intHolder:
DoIntThing(intHolder.Value);
break;
...
}
See also: Switch statements with patterns.
However, the idea behind polymorphism is to be able to do things without having to know the specific type. Therefore, re-design the holder classes and have them do the type specific thing themselves:
public abstract class Holder
{
public abstract void DoThing();
}
public abstract class Holder<T> : Holder
{
public abstract T Value { get; }
}
Some examples of specific types:
public class StringHolder : Holder<string>
{
public StringHolder(string value)
{
Value = value;
}
public override string Value { get; }
public override void DoThing()
{
Console.WriteLine($"String of length {Value.Length} is \"{Value}\"");
}
}
public class IntHolder : Holder<int>
{
public IntHolder(int value)
{
Value = value;
}
public override int Value { get; }
public override void DoThing()
{
Console.WriteLine($"The integer {Value} is {(Value % 2 == 0 ? "even" : "odd")}");
}
}
Now you can simply write
holder.DoThing();
... without having to cast.
Update
Your edited question indeed shows a polymorphic version.
Here I want to present another approach which merges Holder and Holder<T> in a single class through the use of interfaces.
public interface IHolder
{
object Value { get; set; }
}
public interface IHolder<T> : IHolder
{
new T Value { get; set; } // The new keyword hides the inherited property.
}
public class Holder<T> : IHolder<T>
{
object IHolder.Value
{
get => Value; // Returns T Holder<T>.Value as object.
set => Value = value is T t ? t : default; // Sets T Holder<T>.Value.
}
public T Value { get; set; }
}
Holder<T> now implements a "neutral" Value property declared in IHolder based on the object type. Since it implements it explicitly (i.e., instead of public object Value we write object IHolder.Value), this property is hidden, unless it is accessed through the interface. This allows you, for example, to declare a List<IHolder> and to retrieve different kinds of Holder<T> values with list[i].Value as object.
But you have a variable Holder<float> floatHolder, you can get the strongly typed float value.
Note that this still allows you do derive more specific types like class FloatHolder : Holder<float>, but it might not even be necessary.
If you intend to work only with derived types, you can mark Holder<T> as abstract and also all the members that must be implemented by the deriving classes. This makes it impossible to create an instance of Holder<T> with new and also allows you to declare abstract methods without body.
community! It's a good question. That was interesting.
I think this is simple solve for this question.
We just need to create a simple constructor like below
public class Holder
{
public string SomeData; // just example data
public Holder()
{
}
public Holder(Holder someData)
{
SomeData = someData.SomeData;
}
}
public class Holder<T> : Holder
{
public T Value;
public Holder(Holder a, T t = default)
:base(a)
{
Value = t;
}
}
public class Programm
{
void Main()
{
var h = new Holder();
var g = new Holder<string>(h);
}
}
I've created a custom attribute where I want to access the the declaring class of the custom attribute property.
For example:
public class Dec
{
[MyCustomAttribute]
public string Bar {get;set;}
}
Here I would like (in the the cass of MyCustomAttribute) to get the type of the declaring class (Dec).
Is this by any means possible?
EDIT: Thanks for the replies everyone. I learned something new today.
As I've written, attributes are instantiated only when you request them with type.GetCustomAttributes(), but at that time, you alread have the Type. The only thing you can do is:
[AttributeUsage(AttributeTargets.Property)]
public class MyCustomAttribute : Attribute
{
public void DoSomething(Type t)
{
}
}
public class Dec
{
[MyCustomAttribute]
public string Bar { get; set; }
}
// Start of usage example
Type type = typeof(Dec);
var attributes = type.GetCustomAttributes(true);
var myCustomAttributes = attributes.OfType<MyCustomAttribute>();
// Shorter (no need for the first var attributes line):
// var myCustomAttributes = Attribute.GetCustomAttributes(type, typeof(MyCustomAttribute), true);
foreach (MyCustomAttribute attr in myCustomAttributes)
{
attr.DoSomething(type);
}
so pass the type as a parameter.
No, it is not - except for by build-time tools like PostSharp, Roslyn, etc.
You need to find a different approach - perhaps passing a Type in as a constructor argument; or (more likely), but having whatever logic you want to be attribute-based be aware of the declaration context; i.e. assuming MyCustomAttribute has a Foo() method, make it Foo(Type declaringType) or similar.
This might also work:
class MyCustomAttribute : Attribute
{
public Type DeclaringType { get; set; }
}
public class Dec
{
[MyCustomAttribute(DeclaringType=typeof(Dec))]
public string Bar { get; set; }
}
I'm writing an application in C#, which supports plugins. Each plugin has to introduce itself, such that application can prepare appropriate environment for it. The current info object looks more less like this:
class FilterInfo
{
public InputInfo[] inputs;
public OutputInfo[] outputs;
bool IsConfigurable;
bool IsPlayable;
string TypeName;
}
This structure will surely expand in future (however, I guess, that not much, it'll maybe double its size). I'm currently thinking on how to implement such info class properly.
In C++ I would do it the following way (I'll strip the class to one field to make the examples more readable):
class FilterInfo
{
private:
std::vector<const InputInfo> inputs;
public:
std::vector<const InputInfo> & GetInputs()
{
return inputs;
}
const std::vector<const InputInfo> & GetInputs() const
{
return inputs;
}
}
Now, the plugin would instantiate a FilterInfo class, fill-in its fields and then return const FilterInfo on request, such that noone may change contents of the info (well, noone should).
In C#, I can only imagine the following "safe" solution:
public interface IInputInfo
{
bool SomeData
{
get;
}
}
public class InputInfo : IInputInfo
{
private bool someData;
public bool SomeData
{
get
{
return someData;
}
set
{
someData = value;
}
}
public bool IInputInfo.SomeData
{
get
{
return someData;
}
}
}
public interface IFilterInfo
{
ReadOnlyCollection<IInputInfo> Inputs
{
get;
}
}
public class FilterInfo : IFilterInfo
{
private InputInfo[] inputs;
public InputInfo[] Inputs
{
get
{
return inputs;
}
set
{
inputs = value;
}
}
public ReadOnlyCollection<IInputInfo> IFilterInfo.Inputs
{
return inputs;
}
}
The plugin will, of course, return IFilterInfo instead of FilterInfo, such that the data is readonly (OK, I know about reflection, the matter is to notify the user, that the data should not be changed). However, this solution looks very clumsy to me - especially when compared to compact version I cited earlier.
Another solution may to be create FilterInfo only with getters, but it would require passing the data into it in some way and probably would end up with a huge constructor with lots of parameters.
Edit: Another solution is to create a struct and return its copy during every request. However, arrays are copied by reference, so I would have to copy them manually each time.
Yet another one is to construct the FilterInfo from the scratch each time anyone requests it, eg.
public FilterInfo Info
{
get
{
return new FilterInfo()
{
IsConfigurable = true,
IsPlayable = false,
Inputs = new[]
{
new InputInfo()
{
// (...)
}
}
}
}
}
Is there an elegant way to solve this problem?
I think you got it almost right the first time:
Define a public IFilterInfo interface in the pluggable assembly that only allows reading.
Implement the interface in a FilterInfo class in the plugin assembly that has internal setters on its properties.
Have a method return a new instance of the FilterInfo class upon request. Convention suggests to use a method instead of a property in cases where a new instance is constructed each time. (If you insist on using a property you could store the instance once it has been constructed and return it through the property)
Example:
In the pluggable assembly:
public interface IFilterInfo {
bool IsPlayable { get; }
bool IsConfigurable { get; }
}
In the plugin assembly:
internal class FilterInfo : IFilterInfo {
public bool IsPlayable { get; internal set; }
public bool IsConfigurable { get; internal set; }
}
public IFilterInfo GetFilterInfo() {
return new FilterInfo() { IsPlayable = true, IsConfigurable = false };
}
Internal setters and a read-only interface should be enough to ensure that the properties aren't modified outside the plugin assembly.
What about setting the setters to private or protected.
public class FilterInfo
{
public InputInfo[] inputs { get; private set; }
public OutputInfo[] outputs { get; private set; };
bool IsConfigurable;
bool IsPlayable;
string TypeName;
public void SetInputs(...)
{
InputInfo[] allInputs;
//do stuff
inputs = AllInput;
}
public void SetOutputs(...)
{
OutputInfo[] allOutputs;
//do stuff
outputs = AllOutput;
}
}
You would be able to have internal methods to set the data or go protected and allow modifying the objects through inheritance.
UPDATE
What about using the internal accessor for the setter. This way nothing will be able to access the setter unless it is declared in the InternalsVisibleTo assembly level attribute, which would be defined in the assembly containing FilterInfo.
The following post gives a good explanation on how to do this using the internal keyword.
Internal Description
UPDATE
Another solution may to be create FilterInfo only with getters, but it would require passing the data into it in some way and probably would end up with a huge constructor with lots of parameters.
According to this the only issue with not having a getter is that you still need to pass in data. The original solution allows this to happen. I guess I might be a little confused. If the plugin is able to change the information in this API which is by reference I am guessing. Then if the application is referencing the same assembly, it too would have the same accessors provided to the plugin. It seems that short of setting the setters to internal and allowing access through attributes would be the only way to achieve that type of functionality. But that wont work in your case because you do not know the assemblies that are referencing your API.
I don't quite sure about what you really want, but it seems the builder pattern is good for this case.
First, the setter or constructor can be marked internal, means that only the assembly can access the constructor or setter. Leave the getter public, it is needed, isn't it?
Then your builder class (assume you are using the constructor injection):
public class FilterInfoBuilder{
public FilterInfoBuilder(InputInfo[] inputInfo){
this.inputInfo = inputInfo;
}
private InputInfo[] inputInfo;
public FilterInfo Create(){
FilterInfo filterInfo = new FilterInfo(inputInfo);
return filterInfo;
}
}
Maybe I misunderstand your requirement though.
EDIT
You can tweak the builder as a dynamic setter though. Now consider using internal setter instead of internal constructor.
public class FilterInfoBuilder{
public FilterInfoBuilder(InputInfo[] inputInfo){
filterInfo = new FilterInfo();
filterInfo.InputInfo = inputInfo;
}
private FilterInfo filterInfo;
public FilterInfo FilterInfo{
get{
return filterInfo;
}
}
public void ChangeInputInfo(InputInfo[] inputInfo){
filterInfo.InputInfo = inputInfo;
}
}
You can use FilterInfoBuilder.FilterInfo to access the FilterInfo class. To modify it, you can create internal methods inside the builder class.
I don't really sure about the solution though, as I haven't found the design in any documented source.
More EDIT
I have another design, only if you can separate the interface between assemblies and make sure the application access the interface and not the class.
example:
public interface IInputInfoSetable{
public InputInfo[] InputInfo{
set;
}
}
public interface IFilterInfo{
public InputInfo[] InputInfo{
get;
}
}
public class FilterInfo: IFilterInfo, IInputInfoSetable{
// implement explicitly both of the interface.
}
Ok, edited the code for clarification:
Question: How can I access the attribute [MyAttr("...")] in TestClassOne/Two from BaseClass.TheAttribute...?
All classes except TestClassOne/Two will be compiled in to my "core" and delivered as a dev-platform to a customer.
The TestClassOne/Two is developed by the customer, so there can be no knowledge of the TestClassOne/Two in the "core".
Code below is compiled into "core" and delivered to customer as dll.
[TestMethod()]
public void AttrTest()
{
var one = new TestClassOne();
var attrOne = one.MyTestProperty.TheAttribute;
var two = new TestClassTwo();
var attrTwo = two.MyTestProperty.TheAttribute;
}
public class MyAttr : Attribute
{
private string _test;
public MyAttr(string test)
{
this._test = test;
}
}
public class BaseClass
{
public string TheAttribute
{
get {
// Here I would like to get the "[MyAttr("...")]" from the classes in the bottom
return null;
}
}
}
public class SubClass : BaseClass
{
}
Code below is developed by customer (using my dll's)
public class TestClassOne
{
[MyAttr("Attribute one")]
public SubClass MyTestProperty = new SubClass();
}
public class TestClassTwo
{
[MyAttr("Attribute two")]
public SubClass MyTestProperty = new SubClass();
}
You can get directly from type Test:
var result = typeof (Test)
.GetField("MyTest", BindingFlags.Public | BindingFlags.Instance)
.GetCustomAttribute<MyAttr>();
Edit 3:
You can walk the call stack, looking for a relevant attribute in a relevant member in a relevant class. Try this:
public class MyAttr : Attribute
{
private string _test;
public MyAttr(string test)
{
this._test = test;
}
public string getAttr()
{
return _test;
}
}
public class BaseClass
{
private string theString;
public BaseClass()
{
StackTrace callStack = new StackTrace();
for ( int i = 0; i < callStack.FrameCount; i++ )
{
Type t = callStack.GetFrame(i).GetMethod().DeclaringType;
foreach ( MemberInfo m in t.GetMembers().Where(x => typeof(BaseClass).IsAssignableFrom(x.Type)) )
{
foreach ( var z in m.GetCustomAttributes(typeof(MyAttr)) )
{
MyAttr theAttr = z as MyAttr;
if ( z!= null )
{
theString = z.getAttr();
return;
}
}
}
}
}
public string Test
{
get {
return theString;
}
}
}
This requires that your customer always initializes the SubClass member inside the class that declares it. If they start deriving TestClassOne or have it and TestClassTwo derive from a common class that initializes the member, this code will break.
With clever use of reflection, you can expand the above code to cover more use cases, but that's beyond the scope of this question.
Edit 2:
No. I'm sorry, but what you're trying to do isn't possible. There's no "normal" way for an instance of SubClass to know if it's being declared in a member field of some other object, or in an element in an array or in a temporary variable in the stack, or whatever. As such, there's no way for that instance to access the attributes of the member field that's declaring it.
(I suppose you might want to try to access the garbage collector to find out where in memory the this object lives, but that's probably way beyond the scope of this problem, and in any case, not something I know how to do.)
I suspect your problem lies elsewhere entirely. Maybe you need to require your customer to make TestClassOne and TestClassTwo derive from a common abstract class. Maybe they need to derive from BaseClass themselves. Maybe you need to add parameters to the constructor. Maybe you need to provide a different interface altogether. We can't know unless you provide more information on your specific business requirements.
Edit:
To access the attributes declared on the MyTest member, try something along these lines:
public class BaseClass
{
public string Test
{
get {
var attr = typeof(Test).GetMembers().Where(x => x.Type == this.GetType()).First().GetCustomAttributes(true);
return null;
}
}
}
This will search class Test for a member with the same type as this and look for attributes on that member.
(I don't have my Visual Studio here, to check the exact Where syntax, but it should be pretty close to that...)
Original Answer:
Your attribute is declared on the MyTest member of class Test. But, you're doing GetCustomAttributes on class SubClass itself.
Try this:
[MyAttr("apa")]
public class SubClass : BaseClass
{
}
public class Test
{
public SubClass MyTest = new SubClass();
}
Should get you what you want.
I've got a class defined like this:
public abstract class Uniform<T>
{
public abstract string GlslType { get; }
...
}
And then a subclass defined like this:
public class UniformInt : Uniform<int>
{
public override string GlslType
{
get { return "int"; }
}
}
And then a method somewhere else that looks like this:
public static string GetCode<T>()
{
var sb = new StringBuilder();
var type = typeof(T);
sb.AppendFormat("struct {0} {{\n", type.Name);
var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
foreach(var f in fields)
{
sb.AppendFormat(" {0} {1};\n", f.FieldType.GetProperty("GlslType").GetValue(???), f.Name);
}
...
}
I'm having trouble filling in the ???s. I believe GetValue expects an instance of the object, but I don't really care what instance it is because they all return the same value. And AFAIK there's no such thing as a public abstract static readonly value, so I have to use properties.
So what can I put in place of those ???s to get back "int" (assuming one the fields was a UniformInt).
As a side: How can I limit fields to only field types that inherit Uniform<>?
You need an instance of UniformInt in order to get the value of a non-static property:
UniformInt someUniformInt = ...
f.FieldType.GetProperty("GlslType").GetValue(someUniformInt, null)
As a side: How can I limit fields to only field types that inherit Uniform?
bool isDerivesFromUniformOfInt = typeof(Uniform<int>)
.IsAssignableFrom(f.FieldType);
or if you don't know the type of T in advance:
bool isDerivesFromUniformOfT = typeof(Uniform<>)
.MakeGenericType(typeof(T))
.IsAssignableFrom(f.FieldType);
The problem is that since your property is not static the compiler doesn't know that they all return the same value. Since your UniformInt is not sealed, another user could inherit from it and override GlslType to return something else. Then UniformInt and all derived classes could be used for your GetCode<T>() method.
A static method would really be the best option. To make sure that you implement them on all classes (something you can't force because static methods can't be abstract) I would write a simple unit test that uses reflection to load all classes that inherit from Uniform<T> and check if they have the static property defined.
UPDATE
When thinking about how Attributes could help and after some experimenting I came up with the following. It definitely won't win a beauty contest but as a learning exercise it was helpful ;)
using System;
using System.Linq;
namespace StackOverflow
{
internal class StackOverflowTest
{
private static void Main()
{
string sInt = UniformInt.GlslType;
string sDouble = UniformDouble.GlslType;
}
}
public abstract class Uniform<B, T> // Curiously recurring template pattern
where B : Uniform<B, T>
{
public static string GlslType
{
get
{
var attribute = typeof(B).GetCustomAttributes(typeof(GlslTypeAttribute), true);
if (!attribute.Any())
{
throw new InvalidOperationException(
"The GslType cannot be determined. Make sure the GslTypeAttribute is added to all derived classes.");
}
return ((GlslTypeAttribute)attribute[0]).GlslType;
}
}
}
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
internal sealed class GlslTypeAttribute : Attribute
{
public string GlslType { get; private set; }
public GlslTypeAttribute(string glslType)
{
GlslType = glslType;
}
}
[GlslType("int")]
public class UniformInt : Uniform<UniformInt, int> // Curiously recurring template pattern
{
}
[GlslType("double")]
public class UniformDouble : Uniform<UniformDouble, double> // Curiously recurring template pattern
{
}
}
The GlslType is not static, so you need an object reference before you can access it's value. The subject of static properties in abstract classes has been covered extensively already, ie:
C#, implement 'static abstract' like methods
Can't define static abstract string property
Solution 1
Add static methods to all derived classes that return the GlslType. Nothing needs to be added to the base class. Can use unit testing + reflection to check for missing implementation. Suggested by Wouter de Kort.
Solution 2
Change Uniform<T> to make GlslType static:
public abstract class Uniform<T>
{
public static string GlslType { get { throw new NotImplementedException("Please override with \"new\" in derived class."); } }
...
}
Change UniformInt to "override" GlslType, keeping the static modifier:
public class UniformInt : Uniform<int>
{
public new static string GlslType
{
get { return "int"; }
}
}
Fill ??? with null, null:
sb.AppendFormat(" {0} {1};\n", f.FieldType.GetProperty("GlslType").GetValue(null,null), f.Name);
Solution 3
Use attributes instead. Something like:
[GlslType("int")]
public class UniformInt : Uniform<int>
{
}
Conclusion
All 3 of these solutions are pretty similar and seem to have the same drawbacks (can't enforce derived class to implement it). Throwing an exception via method 1 or 2 will help find errors quickly, or with 3 I can just skip over classes that don't have the attribute by modifying my fields condition.