Data objects contain f_version fields.

In functions, instead of specific types of objects, I use the universal T.

But the generic type T does not contain the f_version field.

How to force an object of type T to use the f_version field?

public class BF_Load { private int Version; public void Save<T>(object data, string filepath) ... Version = ((T)data).f_version; 
  • And what should the code do if type T does not contain the f_version field? - VladD pm

3 answers 3

You can enter a base type (I prefer interfaces):

 public interface IVersionable { int f_version { get; } } 

Then restrict the generic parameter in the Save method to this type:

 public void Save<T>(object data, string filepath) where T : IVersionable { ... Version = ((T)data).f_version; ... } 

Actually, casting to nothing, the data parameter can be declared immediately with type T :

 public void Save<T>(T data, string filepath) where T : IVersionable { ... Version = data.f_version; ... } 

    I did not quite understand the question, but perhaps you mean this:

     public void Save<T>(object data, string filepath) { var target = (T)Convert.ChangeType(data, typeof(T)); } 

      Most likely, if you need to refer to a specific field, your method is not quite so Generic. Is it really necessary for this method to be universal? If not (which is most likely), I recommend replacing the type of the data parameter with the type in which the f_version field was declared.

      If you still do not like this solution, you can use one of the proposed solutions below:

      a) Add a refinement to type T:

       public void Save<T>(object data, string filepath) where T: BaseType 

      where BaseType is the type in which the f_version field is declared

      b) Pass an anonymous function to the Save method.

       public void Save<T>(object data, string filepath, Action<T,BF_Load> action = null) { if(action != null) { action((T)data, this); } ... } 

      The method itself is called as follows:

       bfLoad.Save(data, filepath, (t, bf) => { bf.Version = t.f_version }); 

      However, in this case, you will have to change the availability of the Version field.

      c) Take advantage of reflection:

       Version = (int)typeof(T).GetField("f_version", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(data); 

      However, I strongly recommend that you first revise the need for the Save method to remain universal.