public interface IParser<T> where T: new()
{
    IList<T> Parse();
}
Above interface is implemented by following abstract class
public abstract class BaseParser<T>: IParser<T> where T : new()
{
   protected abstract string Sql { get;}
   public List<T> Parse()
   {
      // do parsing
      Console.WriteLine(Sql);
   }
}
Following are two concrete implementation of above abstract class
public class EMailParser: BaseParser<Email>
{
    protected override string Sql
    {
        get
        {
            return @"SELECT * FROM emails";
        }
    }
}
public class UrlParser : BaseParser<Url>
{
    protected override string Sql
    {
        get
        {
            return @"SELECT * From Url";
        }
    }
}
Usage:
class Program
{
    static void Main(string[] args)
    {
       if(args[1] == "url")
          Parser<Url>();
       else
          Parser<Email>();
    }
    static void Parse<T>()
    {
       // Create instance based on typof T and then assign to implementaion
       IParser<T> parser = typeof(T) == typeof(Url) ? new UrlParser(): new EmailParser();
       parser.Parse();
    }
}
I want to create instance of EmailParser or UrlParser base on generic type provided in Program.Main method and assign it to interface implemented by BaseParser (abstract class). How can I do this? I know i can solve this problem by modifying Program.Parse<T> as following
static void Parse<T>() where T: new()
{
    IParser<T> parser = typeof(T) == typeof(Url) ? new UrlParser() as BaseParser<T> : new EmailParser() as BaseParser<T>;
    parser.Parse();
}
However I want to know why I can't assign child class instance to interface implemented by abstract class??
I can't understand why following line does not work
IParser<T> parser = typeof(T) == typeof(Url) ? new UrlParser(): new EmailParser();
and why this line work
IParser<T> parser = typeof(T) == typeof(Url) ? new UrlParser() as BaseParser<T> : new EmailParser() as BaseParser<T>;
As per @nawfal answer this line also should not work because BaseParser and BaseParser are different types. Does there exists implicit case for IParser from BaseParser?
I believe the issue is that the compiler doesn't consider the type to which you are assigning the result of the ?: conditional when parsing the conditional. Rather, the ?: is parsed in isolation, so the compiler can't figure out which type to use.
Edit: From section 7.14 of the C# 5.0 specification:
The second and third operands, x and y, of the ?: operator control the type of the conditional expression. If x has type X and y has type Y then:
If an implicit conversion (§6.1) exists from X to Y, but not from Y to X, then Y is the type of the conditional expression.
If an implicit conversion (§6.1) exists from Y to X, but not from X to Y, then X is the type of the conditional expression.
Otherwise, no expression type can be determined, and a compile-time error occurs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With