HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Casting to less generic types

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
genericlesscastingtypes

Problem

The source code, or rather the concept I'd like to get reviewed is what now allows me to do the following during reflection:

object validator;  // An object known to implement IValidation
object toValidate; // The object which can be validated by using the validator.

// Assume validator is IValidation and toValidate string.

IValidation validation
    = Proxy.CreateGenericInterfaceWrapper>( validator );

validation.IsValid( toValidate ); // This works! No need to know about the type.

// Assuming the validator validates strings, this will throw an InvalidCastException.
//validation.IsValid( 10 );


I no longer need to know about concrete types during reflection where I know types will match. It looks kind of like covariance but the result only works because types are guaranteed to match. This allows me to support any type, since no manual type checks need to be done to cast to the correct interface type.

The CreateGenericInterfaceWrapper method uses RunSharp to emit the code. This source code, and an extended explanation can be found on my blog.

My main concerns are:

  • Did anybody encounter such a use case before, and found a better way to solve it?



  • Did I write something which I could just have found in an existing library?



To further clarify why I wrote this solution, I copied the example from my blog of the code I would have to write to be able to use the IsValid method during reflection.

object validator;  // An object known to implement IValidation
object toValidate; // The object which can be validated by using the validator.

// 'validator' can be any type validator which can validate 'toValidate'.

if ( validator is IValidation )
{
    IValidation validation = (IValidation)validator;
    validation.IsValid( (string)toValidate );
}
else if ( validator is IValidation )
{
    IValidation validation = (IValidation)validator;
    validation.IsValid( (int)toValidate );
}
else if ... // and so on to support any possible type ...

Solution

Did anybody encounter such a use case before, and found a better way to solve it?

There's the IEnumerable pattern:

public interface IValidation
{
    bool IsValid(object obj);
}

public interface IValidation : IValidation
{
    bool IsValid(T t);
}

public abstract class BaseValidation : IValidation
{
    public bool IsValid(object obj)
    {
        return IsValid((T)obj);
    }

    public abstract bool IsValid(T t);
}


Whether it's better or not is debatable, but it should at least be familiar to anyone who has to maintain your code.

Code Snippets

public interface IValidation
{
    bool IsValid(object obj);
}

public interface IValidation<T> : IValidation
{
    bool IsValid(T t);
}

public abstract class BaseValidation<T> : IValidation<T>
{
    public bool IsValid(object obj)
    {
        return IsValid((T)obj);
    }

    public abstract bool IsValid(T t);
}

Context

StackExchange Code Review Q#3258, answer score: 7

Revisions (0)

No revisions yet.