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