У меня есть такой абстрактный класс:
public abstract class ResourceFilter<TFilter> : SomeOtherClass
{
public static readonly ResourceFilter<ActorTypeEnum> ActorType = new ActorTypeResourceFilter();
protected ResourceFilter(string name, string friendlyName)
: base(name, friendlyName)
{
}
public abstract string GetFilterDisplay<T>(T filter);
public abstract string GetFilterValue<T>(T filter);
public virtual string GetComparisonValue<T>(T compare)
{
return Value + "_" + GetFilterValue(compare);
}
public abstract TFilter GetDefaultFilter();
protected TFilter TypeCheck<T>(T value)
{
if (value is null)
throw new ArgumentNullException(nameof(value));
if (value is TFilter excpectedType)
return excpectedType;
throw new FriendlyException($"Type {value.GetType()} is not valid for this Resource Filter");
}
}
У которого такая конкреция:
public sealed class ActorTypeResourceFilter : ResourceFilter<ActorTypeEnum>
{
internal ActorTypeResourceFilter()
: base(nameof(ActorType), "Actor Type")
{
}
public override string GetFilterDisplay<T>(T filter)
{
ActorTypeEnum actorType = TypeCheck(filter);
return actorType.FriendlyName;
}
public override string GetFilterValue<T>(T filter)
{
ActorTypeEnum actorType = TypeCheck(filter);
return actorType.Name;
}
public override ActorTypeEnum GetDefaultFilter()
{
return ActorTypeEnum.User;
}
}
Я хочу иметь возможность использовать абстрактный класс в качестве типа класса:
public class ClassToApplyResourceFilter
{
public ResourceFilter ResourceFilter {get; private set;}
}
Я не могу использовать ResourceFilter в качестве типа без предоставления TFilter, что лишает смысла делать его универсальным.





Если вы хотите иметь универсальный тип для поля, вам также необходимо создать универсальный содержащий класс:
public class ClassToApplyResourceFilter<TFilter>
{
public ResourceFilter<TFilter> ResourceFilter { get; private set; }
}
Вы можете использовать Ковариантность и контравариантность (C#), чтобы обеспечить более гибкий подход, но для этого вам необходимо определить interface в качестве базы для абстрактного класса, поскольку в качестве варианта можно указать только параметры универсального типа интерфейса/делегата.
Звучит похоже на stackoverflow.com/questions/353126/…