C#在抽象类中转换泛型T<;T>;动态
这就是我在C#中要做的事情(在C#在抽象类中转换泛型T<;T>;动态,c#,generics,dynamic,C#,Generics,Dynamic,这就是我在C#中要做的事情(在类帮助程序中-没有泛型参数) 这也失败了, List<AbstractClass<object>> data; public void Add<T>(AbstractClass<T> thing) { this.data.Add((AbstractClass<object>) thing); } 列表数据; 公共空添加(抽象类) { this.data.Add((AbstractClass)th
类帮助程序中
-没有泛型参数)
这也失败了,
List<AbstractClass<object>> data;
public void Add<T>(AbstractClass<T> thing)
{
this.data.Add((AbstractClass<object>) thing);
}
列表数据;
公共空添加(抽象类)
{
this.data.Add((AbstractClass)thing);
}
现在我想我可以
List<dynamic> data; // or List<object> data;
public void Add<T>(AbstractClass<T> thing)
{
this.data.Add(thing);
}
列出数据;//或列出数据;
公共空添加(抽象类)
{
这个。数据。添加(东西);
}
但我需要一个约束,即列表命名数据只包含以下类型的元素
ConcreteClass : AbstractClass<OtherClass>
ConcreteClass:AbstractClass
所以我们知道有一个public T Invoke()
函数,但我们不知道它返回什么。这有助于避免拼写错误invock和只在运行时知道的错误
我希望避免每次调用返回泛型类型T的函数时都强制转换为
动态
,也许这对您有用:
public class Program
{
static void Main()
{
var m1 = new Helper<OtherClass>();
m1.Add(new ConcreteClass());
var m2 = new Helper<int>();
m2.Add(new ConcreteClass2());
}
class Helper<T>
{
List<AbstractClass<T>> data = new List<AbstractClass<T>>();
public void Add<T1>(T1 thing) where T1 : AbstractClass<T>
{
this.data.Add(thing);
}
}
class AbstractClass<T> { }
class OtherClass { }
class ConcreteClass : AbstractClass<OtherClass> { }
class ConcreteClass2 : AbstractClass<int> { }
}
公共类程序
{
静态void Main()
{
var m1=新助手();
m1.添加(新的ConcreteClass());
var m2=新助手();
m2.增加(新混凝土类别2());
}
类助手
{
列表数据=新列表();
公共void Add(T1 thing),其中T1:AbstractClass
{
这个。数据。添加(东西);
}
}
类抽象类{}
类其他类{}
类ConcreteClass:AbstractClass{}
类ConcreteClass2:AbstractClass{}
}
要想做你想做的事,你需要使用
公共类程序
{
静态void Main()
{
var m=新助手();
m、 添加(新的ConcreteClass());
m、 过程();
}
类助手
{
列表数据=新列表();
公共作废添加(IAbstractClass对象)
{
这个。数据。添加(东西);
}
公共程序()
{
foreach(data.Where(x=>x.shouldbeeprocessed())中的变量c)
{
var b=c.Invoke();
控制台。写线(b.问题);
var castData=b作为其他类;
if(castData!=null)
Console.WriteLine(castData.Answer);
}
}
}
公共接口IAbstractClass
{
bool应该被处理();
T Invoke();
}
抽象类AbstractClass:IAbstractClass
{
公共bool应该被处理()
{
返回true;
}
公共摘要T Invoke();
}
类ConcreteClass:AbstractClass
{
公共重写其他类调用()
{
返回新的OtherClass();
}
}
类OtherClassBase
{
公共字符串问题{get{return“生命、宇宙和一切的答案是什么?”;}
}
类OtherClass:OtherClassBase
{
公共int应答{get{return 42;}}
}
}
您不需要告诉Add
您要传递的是什么类型的类,重要的是它派生自指定的类型。您可以执行public void Add(IAbstractClass事情)
并且每个类都可以工作,但是Invoke()
只会返回foreach循环中的对象
您需要找出您希望
Invoke()
返回的最派生的类是什么,这就是您在列表中设置为类型的类。为什么不将数据声明为列表数据
?包含列表数据的类不是T类型。Add(…thing)
函数必须处理添加许多不同的具体对象,这些对象扩展了AbstractClass,而不知道T是什么。我希望这有点道理。这就是类帮助程序{…列出数据;public void Add(…数据){…}..}
除了单个实例帮助程序需要能够接受扩展抽象类、AbtrasctClass、。。。AbtrasctClass
ConcreteClass : AbstractClass<OtherClass>
public class Program
{
static void Main()
{
var m1 = new Helper<OtherClass>();
m1.Add(new ConcreteClass());
var m2 = new Helper<int>();
m2.Add(new ConcreteClass2());
}
class Helper<T>
{
List<AbstractClass<T>> data = new List<AbstractClass<T>>();
public void Add<T1>(T1 thing) where T1 : AbstractClass<T>
{
this.data.Add(thing);
}
}
class AbstractClass<T> { }
class OtherClass { }
class ConcreteClass : AbstractClass<OtherClass> { }
class ConcreteClass2 : AbstractClass<int> { }
}
public class Program
{
static void Main()
{
var m = new Helper();
m.Add(new ConcreteClass());
m.Process();
}
class Helper
{
List<IAbstractClass<OtherClassBase>> data = new List<IAbstractClass<OtherClassBase>>();
public void Add(IAbstractClass<OtherClassBase> thing)
{
this.data.Add(thing);
}
public void Process()
{
foreach(var c in data.Where(x => x.ShouldBeProcessed()))
{
var b = c.Invoke();
Console.WriteLine(b.Question);
var castData = b as OtherClass;
if (castData != null)
Console.WriteLine(castData.Answer);
}
}
}
public interface IAbstractClass<out T>
{
bool ShouldBeProcessed();
T Invoke();
}
abstract class AbstractClass<T> : IAbstractClass<T>
{
public bool ShouldBeProcessed()
{
return true;
}
public abstract T Invoke();
}
class ConcreteClass : AbstractClass<OtherClass>
{
public override OtherClass Invoke()
{
return new OtherClass();
}
}
class OtherClassBase
{
public string Question { get { return "What is the answer to life, universe, and everything?"; } }
}
class OtherClass : OtherClassBase
{
public int Answer { get { return 42; } }
}
}