gpt4 book ai didi

c# - 动态类是这种情况还是……?

转载 作者:太空狗 更新时间:2023-10-30 01:25:09 26 4
gpt4 key购买 nike

关于这个问题我甚至不知道该搜索什么,所以我想把它贴在这里。
假设我有很多接口,比如…

/// <summary>
/// All interesting classes will implement this interface
/// </summary>
interface IMasterInterface {}

/// <summary>
/// Interface to represent someone that creates / produces goods
/// </summary>
interface IProduceGoods : IMasterInterface { int Prop1 {get;} }

/// <summary>
/// Interface to represent someone that buys / consumes goods
/// </summary>
interface IConsumeGoods : IMasterInterface { int Prop2 {get;} }

/// <summary>
/// Interface to represent someone that stores goods
/// </summary>
interface IStoreGoods : IMasterInterface { double Prop3 {get;} string name {get;}}

/// <summary>
/// Interface to represent someone that enjoys looking at goods
/// </summary>
interface IEnjoyLookingAtGoods : IMasterInterface { int Prop4 {get;} DateTime Prop5 {get;} }

现在,我有一些我知道我今天想要的组合,比如:
/// <summary>
/// Class to represent a farm which grows and stores crops
/// </summary>
class Farm : IProduceGoods, IStoreGoods {/*...*/}

/// <summary>
/// Class to represent a merchant who buys goods and stores them
/// </summary>
class Merchant : IConsumeGoods, IStoreGoods {/*...*/}

/// <summary>
/// Window Shopper represents someone who doesn't buy anything and only looks
/// </summary>
class WindowShopper : IEnjoyLookingAtGoods{ /*...*/ }

现在我很高兴我有了几节课,但是明天,我想,如果有人真的从商家那里买了一节课,我会去我的代码并添加
/// <summary>
/// Princesses have lots of money to buy stuff and lots of time to look at stuff
/// </summary>
class Princess : IEnjoyLookingAtGoods, IConsumeGoods {/*...*/}

现在,我觉得我不应该这么做…
我想做的是有一个工厂(或类似的工厂)并说:
IMasterInterface princess = MyFactory.Create(IEnjoyLookingAtGoods, IEnjoyLookingAtGoodsParameters, IConsumeGoods, IConsumeGoodsParameters)

/// This should be true
((princess is IEnjoyLookingAtGoods) && (princess is IConsumeGoods))

本质上,我想告诉工厂使用哪些接口来构造对象。我有一个容器,上面有一个imasterinterface列表
/// <summary>
/// My container class for interesting objects
/// </summary>
class InterestingObjectContainer
{ public ReadOnlyCollection<IMasterInterface> InterestingObjects {get;} }

现在,问题的关键就在这里。让所有感兴趣的类实现imasterinterface的原因是能够有一个列表并使用更具体的接口作为过滤器。或许以下几点会更清楚:
/// <summary>
/// I want to see the net population of producers and get there total production
/// </summary>
class ProducerProductionCalculator
{
// THIS IS WHERE THE MEAT OF THE QUESTION RESIDES!
ProductionResults Calculate(InterestingObjectContainer interestingObject)
{
List<IProduceGoods> producers = interestingObject.InterestingObjects.OfType<IProduceGoods>(); // Perhaps more interest LINQ
return DoSomethingWithListToAggregate(producers);
}
}

通过过滤到更具体的接口,我现在可以指望传递给
DosomethingWithListToAggregate(ICollection生产者)
具有iproducegoods类的方法/属性。
我考虑过用字典和字符串属性查找来实现这一点,但感觉我可以用这种方式编写更强类型的代码,并确保某个地方的简单拼写错误不会把一切都弄糟。
总之,我想总结如下:
这是一种在对象上实现变量属性的糟糕方法吗?如果是的话,还有更好的方法。如果没有,是否有办法在工厂中创建对象,正如我在上面解释的那样?
编辑:
我觉得做这个主意不错,很酷。我想知道如何创建一个工厂,它接受一个接口的参数,这个接口只有属性,而且属性只有getter(我认为这是一个重要的点)和属性的属性值,并返回一个实现接口并定义了所有属性的对象。
例如,
/// <summary>
/// Factory to create any combination of properties
/// </summary>
class FactoryForInterestingObjects
{
public static IMasterInterface Create(
List<KeyValuePair</*what goes here is the interface that I want to use,
what goes here are the parameter values that
should be returned by the getter */>> );
}

我将把所有接口及其参数值传递给工厂,它将创建一些实现这些接口并具有这些值的类。希望这更清楚一点?
编辑2:如何使用decorator?
根据我对decorator的了解,您可以扩展对象的功能。太酷了。但是,您必须提前知道如何扩展该功能。你不能随便这么做。
考虑到我的代码基础如上所述,我想使用decorator。
我会说:
// Edited to be correct
class EnjoyLookingDecorator : IEnjoyLookingAtGoods
{
private IMasterInterface instance;
public EnjoyLookingDecorator(IMasterInterface wrappedObject)
{ this.instance = wrapped Object;}

#region Implementation of IEnjoyLookingAtGoods
/*...*/
#endregion
}

编辑4:
我还是觉得这样不行。在您的示例中,我失去了包含的类接口,我必须将其重定向下来。例如,
class EnjoyLookingDecorator : IEnjoyLookingAtGoods
{
private IMasterInterface instance;
public EnjoyLookingDecorator(IMasterInterface concrete)
{ this.instance = concrete;}

#region Implementation of IEnjoyLookingAtGoods here
/*...*/
#endregion

bool Is<T>() //this should be in the IMasterInterface
{
return this is T or instance is T;
}
}

class ConsumesGoodsDecorator : IConsumeGoods
{
private IMasterInterface instance;
public ConsumesGoodsDecorator (IMasterInterface concrete)
{ this.instance = concrete;}

#region Implementation of IConsumeGoods here
/*...*/
#endregion

bool Is<T>()
{
return this is T or instance is T;
}
}

所以当你
IMasterInterface princess = new MasterClass() //whatever your concrete type is named
princess = new ConsumesGoodsDecorator(new EnjoyLookingDecorator(princess))

你再也做不到公主。财产你的外表看起来像装饰你失去了所有的财产。这不是我想要的。保留属性的唯一方法是重定向
class ConsumesGoodsDecorator : IConsumeGoods, IEnjoyLookingAtGoods
{
private IMasterInterface instance;
public ConsumesGoodsDecorator (IMasterInterface concrete)
{ this.instance = concrete;}

#region Implementation of IConsumeGoods here
/*...*/
#endregion

#region Redirect all the IEnjoyLookingAtGoods Property Getters to instance
/* ... */
#endregion

bool Is<T>()
{
return this is T or instance is T;
}
}

通过执行重定向,我们必须实现接口。然后所有的组合都必须有代码,这是我试图避免的。我不需要限制接口的组合。
编辑5:
也许我的问题还不清楚。想象一下上面的接口,它们的属性被填充。
如果工厂能这样做:
/// <summary>
/// Factory to create any combination of properties
/// </summary>
class FactoryForInterestingObjects
{
public static IMasterInterface Create(
List<KeyValuePair<Type t, ArgSet customArguments>> interfaces))
{
object baseObject;
foreach(KeyValuePair<Type, ArgSet> interface in interfaces)
{
AddInterface(interface, object);
}
}

private static void AddInterface(KeyValuePair<Type, ArgSet> interface, ArgSet arguments)
{
// Delegate this to someone else
if(interface.Key is typeof(IProduceGoods))
{
IProduceGoodsExtensions.AddInterface(o, interface.value);
}
}
}

public static class IProduceGoodsExtensions
{
public static void AddInterface(object o, ArgSet arguments)
{
// do something to object to make it implement IProductGoods
// and make all the getters return the arguments passed in ArgSet
}
}

我意识到这并不是它真正的工作方式,但它说明了我试图表达的观点。我希望对象实现接口的动态组合,并具有setter的默认值。
即使我可以让工厂写一个包含代码的文本文件:
/// <summary>
/// Auto Generated by Factory to create a new type on the fly
/// </summary>
class ClassImplementingIProduceGoodsAndIEnjoyLookingAtGoods : IProduceGoods, IEnjoyLookingAtGoods
{
// From IProduceGoods
public int Prop1 {get; private set;}
// From IEnjoyLookingAtGoods
public int Prop4 {get; private set;}
public DateTime Prop5 {get; private set;}
public ClassImplementingIProduceGoodsAndIEnjoyLookingAtGoods(int prop1, int Prop4 , DateTime Prop5)
{
this.Prop1 = prop1; this.Prop4 = Prop4; this.Prop5 = Prop5;
}
}

然后编译这个类并以某种方式允许我创建它的实例。这就是我要找的。希望这更有意义。
编辑6:
这是我可能会采用的解决方案,因为我在这一点上看不到替代方案。
//Update Master Interface
interface IMasterInterface
{
bool Is(Type t);
IMasterInterface As(Type t);
}

/// <summary>
/// Class to build up a final object
/// </summary>
class CompositionObject : IMasterInterface
{
ICollection<IMasterInterface> parts;
CompositionObject(IMasterInterface object){ parts = new List<IMasterInterface(object);}
bool Is(Type t)
{
foreach(IMasterInterface part in parts)
{ if (part is t) return true; // not sure on this off top of head
}
return false;
}

IMasterInterface As(Type t)
{
foreach(IMasterInterface part in parts)
{ if(part is t) return part; }
}

bool Add(IMasterInterface interface)
{ this.Is(typeof(interface)) return false; // don't add again
this.parts.Add(interface) }
}

现在我的工厂可以只返回这些组合对象,只要被调用,我就可以安全地向下转换。我觉得可能有一种方法可以使用泛型来避免强制转换。
任何实现imasterinterface的具体类都可以在调用as时简单地返回自身。
编辑3:
谢谢大家的评论。我很高兴我公布了我对这个图案的无知;谢谢你的澄清!我爱这个网站和所有可爱的人在那里!啊!

最佳答案

试着看看装饰设计模式。就我所见,它是针对您所想到的那种情况,即对象可以包含从一组属性中提取的一组混合属性。在decorator模型中,每个属性都是一个自己的类,您可以有效地动态连接这些类以创建具有所需属性的对象。
要实现过滤,您需要使用某种迭代器遍历装饰器链,以查看您要测试的对象是否包含您要查找的迭代器。
我还没有使用C语言中的装饰器,只是C++,但是我发现它是一种非常有用和灵活的方法。如果你发现自己创建了更多更专业的类来表示“property”类的交集,那么我认为decorator很有帮助。
有关此模式的信息,请参见Decorator Design Pattern in C#。(购买并阅读gof设计模式书!)

关于c# - 动态类是这种情况还是……?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7583632/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com