我有一个简短的问题。这段代码似乎有些不对劲。我想利用泛型和代理,如果适用的话,很可能利用泛型代表。我正在使用一些代码生成的api,并且生成的对象非常相似。我看到他们都实现了一个接口,所以我尝试用一些方法创建一个类来处理不同的场景。这是一些示例代码。在很多层面上都感觉不对劲。请告诉我如何使这段代码更好。如果你愿意,可以提供一些重构建议。并且无论如何都要撕成碎片。我想更好地编码并学会正确地做事。
private delegate IsomeEntity DisplayDelegate(IsomeEntity display);
public IsomeEntity Display<T>()
{
DisplayDelegate _del = null;
IsomeEntity display = factory.CreateObject(typeof(T).Name);
if (display.GetType() == typeof(ADisplayEntity))
_del = ADisplayEntity;
if (display.GetType() == typeof(BDisplayEntity))
_del = BDisplayEntity;
if (display.GetType() == typeof(CDisplayEntity))
_del = CDisplayEntity;
return _del(display);
}
public ADisplayEntity ADisplayEntity(IsomeEntity display)
{
ADisplayEntity ade = display as ADisplayEntity;
try
{
ADisplay o = new ADisplay();
ADisplayEntity response = o.ADisplay(ade);
return response;
}
catch (Exception ex)
{
Exception newEx;
if (someExceptionHandler.HandleException(ex, this, out newEx))
throw newEx;
}
return null;
}
public BDisplayEntity BDisplayEntity(IsomeEntity display)
{
BDisplayEntity dde = display as BDisplayEntity;
try
{
BDisplay o = new BDisplay();
BDisplayEntity response = o.BDisplay(bde);
return response;
}
catch (Exception ex)
{
Exception newEx;
if (someExceptionHandler.HandleException(ex, this, out newEx))
throw newEx;
}
return null;
}
答案 0 :(得分:0)
您可以将委托和lambda函数作为通用值传递,如下所示:
public ISomeEntity Display<T>( Func<T, ISomeEntity> conversion )
{
IsomeEntity display = factory.CreateObject(typeof(T).Name);
return conversion(display);
}
然后调用它:
var myNewEntity = Display(
x => ADisplay.GetADisplay(x as ADisplayEntity) );
等等。
我不完全确定你要做什么 - 所以我的代码可能不太正确,但它应该让你知道如何传递lambda。
您甚至可以将它们存储在词典中并进行查找。
答案 1 :(得分:0)
好的,如果我正确地关注你,ADisplayEntity
和BDisplayEntity
都是生成的类看起来几乎一样,对吧?并且您正在尝试创建某种通用委托工厂方法(您称之为Display<T>
),允许调用者指定他们想要的显示实体的类型,作为您创建的单个接口进行转换实体实施,是吗?我认为ADisplay
和BDisplay
类没有实现常见的Display()
方法,这就是您调用ADisplay
和BDisplay
的原因。嗯......那些与班级同名。错字?您列出的内容甚至无法编译。
我认为需要一个更好的例子。我意识到你正在尝试清理代码,但也许一些名称更改的真实代码可能会更好。我想看看ADisplay
,BDisplay
,ADisplayEntity
和BDisplayEntity
到底是什么。
那就是说,如果各种A/BDisplay
和A/BDisplayEntity
类真的如此不同以至于你无法将这些委托方法合并到一个方法中,那么你几乎可以做你唯一能做的事情实现你的最初目标。
也许有更多信息我可以提供更好的答案,但我在这里看不太重要。除了您的方法的名称与它们实例化的类名称相同,以及您调用与该类名称相同的方法。
答案 2 :(得分:0)
为什么不简单?你为什么需要代表..等等。
public static ISomeEntity DisplayEntity(ISomeEntity display)
{
ISomeEntity result;
if (entity is ADisplayEntity)
{
ADisplay disp = new ADisplay();
result = disp.ADisplayFunc();
}
if(entity is BDisplayEntity)
{
BDisplay disp = new BDisplay();
result = disp.BDisplayFunc();
}
return result;
}
当然,如果您可以使用 ADisplay 并且 BDisplay 也遵循界面,例如 IDisplay ,则更有意义,那么您只需要返回 IDisplay.Display(ISomeEntity)
接下来你可以像这样包装你的<< ..
public interface IDisplay
{
public ISomeEntity Display(ISomeEntity entity);
}
public class AWrappedDisplay: IDisplay
{
public ISomeEntity Display(ISomeEntity entity)
{
ADisplay disp = new ADisplay();
return disp.ADisplayFunc(entity);
}
}
public class BWrappedDisplay : IDisplay
{
public ISomeEntity Display(ISomeEntity entity)
{
BDisplay disp = new BDisplay();
return disp.BDisplayFunc(entity);
}
}
public static IDisplay Factory(Type t)
{
IDisplay disp = null;
if (t == typeof(ADisplayEntity))
disp = new AWrappedDisplay();
if (t == typeof(BDisplayEntity))
disp = new BWrappedDisplay();
return disp;
}
然后你可以像这样调用你的DisplayEntity
public static ISomeEntity DisplayEntity(ISomeEntity display)
{
IDisplay disp = Factory(display.GetType());
ISomeEntity newDisplayEntity = disp.Display(display);
return newDisplayEntity;
}
答案 3 :(得分:0)
如果你想推广这些方法,你可以这样做:
private delegate IsomeEntity DisplayDelegate<T>(IsomeEntity display);
public IsomeEntity DisplayMethod<T>() where T : IsomeEntity
{
DisplayDelegate<T> _del = new DisplayDelegate<T>(DoDisplay<T>);
IsomeEntity entity = factory.CreateObject(typeof(T).Name);
return _del(entity);
}
public IsomeEntity DoDisplay<T>(IsomeEntity entity)
{
try
{
Display<T> o = new Display<T>();
Entity<T> response = o.Display(entity);
return response;
}
catch (Exception ex)
{
if (someExceptionHandler.HandleException(ex, this, out newEx))
throw newEx;
}
}
在这种情况下,实际上不需要委托,您可以直接调用DoDisplay。
public IsomeEntity DisplayMethod<T>() where T : IsomeEntity
{
IsomeEntity entity = factory.CreateObject(typeof(T).Name);
return DoDisplay<T>(entity);
}
public IsomeEntity DoDisplay<T>(IsomeEntity entity)
{
try
{
Display<T> o = new Display<T>();
Entity<T> response = o.Display(entity);
return response;
}
catch (Exception ex)
{
if (someExceptionHandler.HandleException(ex, this, out newEx))
throw newEx;
}
}
答案 4 :(得分:0)
我要假设,因为你提到自动生成了修改ISomeEntity的东西在窗口外(否则我建议在ISomeEntity中添加一个Display()方法,然后直接通过接口在实体上调用它。每个实体都会实现自己的Display()版本。
所以,如果我理解你的代码正在尝试做什么(它不是很清楚),我建议创建一个IDisplay接口,让ADisplay和BDisplay继承它。这个接口有一个方法Display(),它接受ISomeEntity并返回ISomeEntity。但是,如果ADisplay.Display(ISomeEntity)收到BDisplayEntity,则会抛出异常。
然后,我将创建一个IDictionary,您将其存储为具有该主要Display方法的类中的字段(我将其称为Displayer)。这个字典将存储每种类型使用的IDisplay(即typeof(ADisplayEntity) - > new ADisplay())。
然后您可以将主要的Display方法添加到Displayer,但现在让它返回一个通用T,因为T是您正在创建和返回的类型。此方法查找它需要的IDisplay,并在工厂创建的ISomeEntity上使用它,并返回其结果。
使用词典意味着你不会得到一堆糟糕的if语句,只需添加到字典就可以轻松添加更多IDisplays。
这是我的代码,它在VS2008中编译。
public interface ISomeEntity
{
}
public class EntityFactory
{
public ISomeEntity CreateObject(string name)
{
//Do factory stuff here
return null;
}
}
public class ADisplayEntity : ISomeEntity
{
}
public class BDisplayEntity : ISomeEntity
{
}
public interface IDisplay
{
ISomeEntity Display(ISomeEntity entity);
}
public class ADisplay : IDisplay
{
public ISomeEntity Display(ISomeEntity entity)
{
ADisplayEntity aEntity = entity as ADisplayEntity;
if (aEntity == null)
throw new ArgumentException("Wrong type");
//Do whatever happens when you convert parameter entity into a
//"response" ADisplayEntity. I'm just returning a new
//ADisplayEntity to make it compile for me
return new ADisplayEntity();
}
}
public class BDisplay : IDisplay
{
public ISomeEntity Display(ISomeEntity entity)
{
BDisplayEntity bEntity = entity as BDisplayEntity;
if (bEntity == null)
throw new ArgumentException("Wrong type");
//Do whatever happens when you convert parameter entity into a
//"response" BDisplayEntity. I'm just returning a new
//BDisplayEntity to make it compile for me
return new BDisplayEntity();
}
}
public class Displayer
{
private IDictionary<Type, IDisplay> displayers;
private EntityFactory factory;
public Displayer()
{
factory = new EntityFactory();
displayers = new Dictionary<Type, IDisplay>
{
{ typeof(ADisplayEntity), new ADisplay() },
{ typeof(BDisplayEntity), new BDisplay() }
};
}
public T Display<T>() where T : class, ISomeEntity
{
T entity = factory.CreateObject((typeof(T).Name)) as T; //Type-safe because of the factory
IDisplay displayer = displayers[typeof(T)];
return displayer.Display(entity) as T; //Typesafe thanks to each IDisplay returning the correct type
}
}