C# 访问从泛型抽象基派生的类中重写的抽象属性所需的接口?
因此,我的困境是,为了从C# 访问从泛型抽象基派生的类中重写的抽象属性所需的接口?,c#,oop,generics,interface,abstract-class,C#,Oop,Generics,Interface,Abstract Class,因此,我的困境是,为了从UtilityThing访问IntThing或StringThing的MyProperty,我定义了一个MyProperty接口,并将其用作UtilityThing中T的通用约束。这是可行的,但考虑到抽象库中已经定义了相同的属性,这似乎是多余的。我是否遗漏了设计的一个方面,或者这实际上是在这个例子中需要完成的方式 public interface IThing { string MyProperty { get; set; } } public abstrac
UtilityThing
访问IntThing
或StringThing
的MyProperty
,我定义了一个MyProperty
接口,并将其用作UtilityThing
中T
的通用约束。这是可行的,但考虑到抽象库中已经定义了相同的属性,这似乎是多余的。我是否遗漏了设计的一个方面,或者这实际上是在这个例子中需要完成的方式
public interface IThing {
string MyProperty { get; set; }
}
public abstract class Thing<T> {
protected string _MyProperty;
public abstract string MyProperty { get; set; }
public T OtherProperty { get; set; }
public string CommonMethod() {
return MyProperty + "foobar";
}
}
public class IntThing : Thing<int?>, IThing {
public override string MyProperty {
get { return _MyProperty; }
set { _MyProperty = value + OtherProperty.ToString(); }
}
}
public class StringThing: Thing<string>, IThing {
public override string MyProperty {
get { return _MyProperty; }
set { _MyProperty = OtherProperty + value; }
}
}
public class UtilityThing<T> where T: IThing, new() {
public T DoIt(SomeContext someContext, string name) {
string contextVal = someContext.GetValue(name);
var thing = new T { MyProperty = contextVal }
return thing;
}
}
public接口信息{
字符串MyProperty{get;set;}
}
公共抽象类事物{
受保护的字符串\u MyProperty;
公共抽象字符串MyProperty{get;set;}
公共T其他属性{get;set;}
公共字符串CommonMethod(){
返回MyProperty+“foobar”;
}
}
公共类IntThing:Thing,IThing{
公共重写字符串MyProperty{
获取{return\u MyProperty;}
设置{u MyProperty=value+OtherProperty.ToString();}
}
}
公共类StringThing:Thing{
公共重写字符串MyProperty{
获取{return\u MyProperty;}
设置{u MyProperty=OtherProperty+value;}
}
}
公共类实用程序thing,其中T:IThing,new(){
公共T DoIt(SomeContext SomeContext,字符串名){
字符串contextVal=someContext.GetValue(名称);
var thing=newt{MyProperty=contextVal}
归还物;
}
}
您需要引入新的泛型类型。一旦引入了新类型,就可以消除对接口的需求
public class UtilityThing<T, I> where T : Thing<I>, new()
{
public T DoIt(SomeContext someContext, string name)
{
string contextVal = someContext.GetValue(name);
var thing = new T { MyProperty = contextVal };
return thing;
}
}
公共类实用程序Thing,其中T:Thing,new()
{
公共T DoIt(SomeContext SomeContext,字符串名)
{
字符串contextVal=someContext.GetValue(名称);
var thing=newt{MyProperty=contextVal};
归还物;
}
}
您可以这样使用它:
var utility = new UtilityThing<IntThing, int?>();
var utility=new UtilityThing();
但是东西是抽象的,不能实例化。@BrettRossier你不是在实例化抽象类,你是在实例化具体的IntThing或StringThing,你只是说t必须从抽象类派生。我已经编辑了我的responseHmm,这是可行的,但它本质上将冗余转移到了实用程序的通用参数中。另外,由于IntThing
与Thing
之间缺乏可兑换性,示例的原始使用部分可能会失败(IntThing
是东西,而不是东西)。我希望避免这种用法,尽管它会在编译时被捕获。如果C#根据约束进行更多的类型推断,那就太好了UtilityThing
将推断约束中所需的类型,其中T:Thing
@BrettRossier-类型推断已经是编译器中最复杂的部分之一,有时会导致指数复杂性。为了简化实现,他们决定要么全部推断,要么什么都不推断。如果要指定一种类型,则必须指定所有类型。当然,对于不提供附带的非泛型工厂类的类(而不是方法),你根本没有推论。我已经更新了我的答案)通常的方法是引入另一个抽象类Thing
,它包含Thing
的非泛型成员,然后让Thing
派生自Thing
@Damien\u不信者你会移动哪些成员?MyProperty实现依赖于OtherProperty;),我希望它保持抽象,以便派生类需要它的实现。