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<>?
The problem is that since your property is not static the compiler doesn’t know that they all return the same value. Since your
UniformIntis not sealed, another user could inherit from it and overrideGlslTypeto return something else. ThenUniformIntand all derived classes could be used for yourGetCode<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 😉