BuZz
BuZz

Reputation: 17465

Calling Generic Method on Generic Field?

I have the following and at some point I need to create Failures for Validations. We suppose each type deriving from Validation has one and only one type deriving from Failure<T> where T is the aforementioned implementation of Validation.

As I have a growing number of implementations of Validation, I need to be able to instantiate the right type deriving from Failure<T>, and call the link method on it within a method that looks like

void recordFailureForValidation(Validation v) {
   Type failureType = dict[v.GetType()];
   Object failure = Activator.CreateInstance(failureType);
       // how do I call failure.link(v) ?
}

At Runtime, a dictionary gives me the type deriving from Failure<T> given T. I am able to instantiate Failure<T> (Failure1, Failure2, etc...), but I can't find how to call link on the public field reference of my newly created Failure instance (by making all uses that made sense to me of GetMethod, MakeGenericMethod, Invoke, etc...)

public class MyReferenceClass<T>
  where T : Object, new() {
   public void link(T arg) { ... }
}

public abstract class Failure<T>
   where T : ValidationRule, new() {
...
   public MyReferenceClass<T> reference;
...
}

public class Failure1 : Failure<Validation1> {
}

public class Failure2 : Failure<Validation2> {
}


public abstract class ValidationRule {
   ...
}

public class ValidationRule1 : ValidationRule {
...
}

public class ValidationRule2 : ValidationRule {
...
}

Upvotes: 1

Views: 106

Answers (2)

D Stanley
D Stanley

Reputation: 152556

link is private since you do not specify a different accessibility. Make it public or internal:

public class MyReferenceClass<T>
  where T : Object, new() {
   public void link(T arg) { ... }
}

then you can call it from Failure<T> through the reference property:

public abstract class Failure<T>
   where T : ValidationRule, new()
{
    protected T Validation {get; set;};
    public MyReferenceClass<T> reference;
}

public class Failure1 : Failure<Validation1>
{
    public void Test()
    {
        this.reference.link(Validation);
    }
}

Upvotes: 1

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112352

Let Failures implement a non generic IFailure interface as well as a generic one in the same manner as IEnumerable and IEnumerable<T>

Create an abstract factory method within ValidationRule that has to be implemented by each concrete Validation

public ValidationRule1 : ValidationRule
{
    public override IFailure ToFailure()
    {
        return new Failure1(this);
    }

    ...
}

Upvotes: 1

Related Questions