上下文:
我想拥有两个库 - 一个是使用现有实现的遗留库,另一个是带有验证等的一些流程的更精简版本。此外,从长远来看,删除多余的数据。
我在非遗留库中有两个接口:
public interface IMyAttribute
{
int Id { get; set; }
dynamic Value { get; set; } // if Value can be of different types, is there a better way?
bool IsValid();
}
public IMyData
{
List<IMyAttribute> data { get; set; };
void SetProperties();
bool IsValid();
}
我将遗留库设置为引用&#34; new&#34;图书馆。对于IMyAttribute的遗留实现,IsValid返回true,因为目前没有现有的验证。这将从一个表中提取数据,该表将设置其AttributeValue,AttributeValueNumber或AttributeValueDate字段,并且应该相应地表现(string,double,DateTime),因此使用动态Value。对于IMyData的遗留实现,我已经向对象添加了属性,而SetProperties设置了该实例的属性。
我的问题是,我基本上与它看起来的界面有关。或者更确切地说,我尝试这样做的方式我似乎只能链接到界面。我的目标是&#34;我将拥有带有这些参数的方法,这些或多或少的回报。&#34;但是我试图这样做并遇到问题:
public class MyLegacyAttribute : IMyAttribute
{
//implementing items from interface plus other methods and properties
}
public class MyLegacyData : IMyData
{
...
List<MyLegacyAttribute> data { get; set; }
...
}
有没有一种方法可以这样做,保持合同性质,还是我处理错误?我尝试将IMyData修改为:
List<T> data where T : IMyAttribute { get; set; }
List<T> data { get; set; } where T : IMyAttribute // didn't think this would work, but gave it a shot.
无济于事。
答案 0 :(得分:1)
根本不清楚你的具体问题是什么。如果你提供一个很好的Minimal, Complete, and Verifiable code example来清楚显示你正在尝试做什么,以及精确描述该代码现在正在做什么,那将会有所帮助,以及它与你想要它做的有什么不同。非常具体。
与此同时,我可以提供一些可能会有所帮助的想法。
首先,不要在界面中使用dynamic
。没有意义。如果您不能使界面通用,那么只需使用object
。如果确实需要该功能,则使用该接口的代码可以将object
分配给dynamic
。更有可能的是,它也应该不使用dynamic
,而应该转换为已知类型并以这种方式访问成员。
但最好是,您可以使界面通用。即:
public interface IMyAttribute<T>
{
int Id { get; set; }
T Value { get; set; }
bool IsValid();
}
当然,这样做会导致使用该接口的所有代码也必须是类型感知的。但从长远来看,这将是非常好的,因为您将避免出现问题,并且会进行编译时类型检查。
关于MyLegacyData
类型的问题,虽然您对此并不十分清楚,但似乎您遇到的问题是List<MyLegacyAttribute>
不是与List<IMyAttribute>
相同或甚至兼容,即使MyLegacyAttribute
实现IMyAttribute
。原因应该是明确的:MyLegacyData
对象可以被任何其他代码视为IMyData
,然后该代码可以始终访问data
元素(应该恕我拼写{{ 1}})作为Data
。然后,该代码可以尝试将List<IMyAttribute>
的一些实现添加到除实际类型IMyAttribute
所需的MyLegacyAttribute
之外的列表中。
编译器不会让你这么做,原因很充分。
如果您可以使MyLegacyData
成为通用界面,那么您也可以一般定义IMyData
。例如:
MyLegacyData
你可以将这两个想法结合起来:
public IMyData<T> where T : IMyAttribute
{
List<T> data { get; set; };
void SetProperties();
bool IsValid();
}
public class MyLegacyData<T> : IMyData<T> where T : IMyAttribute
{
...
List<T> data { get; set; }
...
}
如果您出于某种原因需要非通用版本,那么您仍然可以创建一个子类:
public interface IMyAttribute<T>
{
int Id { get; set; }
T Value { get; set; }
bool IsValid();
}
public IMyData<TData, TValue> where TData : IMyAttribute<TValue>
{
List<TData> data { get; set; };
void SetProperties();
bool IsValid();
}
public class MyLegacyData<TData, TValue> : IMyData<TData, TValue>
where TData : IMyAttribute<TValue>
{
...
List<TData> data { get; set; }
...
}
或者,如果它只是必须一直输入全名,您可以为该类型添加别名:
public class MyNongenericLegacyData : MyLegacyData<MyLegacyAttribute>
{ }
以上内容可以完全解决您的问题。如果是这样,很好。如果没有,请改进问题,以便更清楚您的问题。