Reputation: 1125
I'm trying to have the generic static function Load()
to call a virtual, but obviously C# compiler won't recognize PostLoad()
in T. I wonder is there a way to accomplish this somehow. Any ideas?
public abstract class Model<T> where T : new()
{
public virtual void PostLoad() { }
public static T Load()
{
T bar;
//assigning values to bar
....
//compilation error: Type `T' does not contain a definition for `PostLoad' and no extension method
bar.PostLoad();
return bar;
}
}
Upvotes: 0
Views: 107
Reputation: 106
I don't know what the class level Load() function should do. But the general rule here is class level function can't call instance functions except if they have access to the object itself then they can call its functions.
I will assume that the Load() function is suppose to load the model. In this case you need to change the return type of the function from T to Model and the type of bar from T to Model. Then initialize and load the model in the way you like assign it to bar then call the post load, like this.
public abstract class Model<T> where T : new()
{
public virtual void PostLoad() { }
public static Model<T> Load()
{
Model<T> bar = null;
//assigning values to bar
//compilation error: Type `T' does not contain a definition for `PostLoad' and no extension method
bar.PostLoad();
return bar;
}
}
Also there is a small mistake in your code, which is that you can calling PostLoad() function on T type and the function is defined in Model.
If you intention is to say T must have a PostLoad() function and that the Load() static function should call it after initialization and load, you should do the following:
public interface IModelLifeCycle
{
void PostLoad();
}
public abstract class Model<T> where T : IModelLifeCycle
{
public static T Load()
{
T bar = default(T);
//assigning values to bar
//compilation error: Type `T' does not contain a definition for `PostLoad' and no extension method
bar.PostLoad();
return bar;
}
}
As you can see now because the where condition is forcing the generic type to implement the IModelLifeCycle the Load() function is able to call the PostLoad() function which is forced by the interface definition not by the Model (You don't need the PostLoad() which is defined in the Model class).
Hope this help.
Upvotes: 0
Reputation: 1125
By adding a generic constraint and move the virtual function to a base class. The compiler will recognize PostLoad()
.
public abstract class Model
{
public virtual void PostLoad() { }
}
public abstract class Model<T> : Model where T : Model, new()
{
public static T Load()
{
T bar;
//assigning values to bar
....
//compilation error: Type `T' does not contain a definition for `PostLoad' and no extension method
bar.PostLoad();
return bar;
}
}
Upvotes: 0
Reputation: 17223
Your abstract class Model<T>
is the class that defines PostLoad
, but type T
does not. T
could be anything, and that is why the compiler is giving you an error. So in your method Load
you need to create a new class that is a Model<T>
if you want to call PostLoad
public abstract class Model<T> where T : new()
{
public virtual void PostLoad() { }
public static T Load()
{
Model<T> model = new ...create some type here...
//assigning values
model.PostLoad();
//now what do you return?
}
}
I think you need to have another look at your design... What is it exactly you're trying to do?
Upvotes: 3