C# 定义强连接到接口的方法的正确方法
我有以下界面:C# 定义强连接到接口的方法的正确方法,c#,C#,我有以下界面: interface IName { string Name { get; } } 还有一些基类基类。此类的子类可以实现IName接口,但并非所有子类都可以实现 如果一个子系统实现了IName,我还希望重写ToString()方法,这与所有情况完全相同,如下所示: public override string ToString() { return Name; } 似乎重写ToString()的好地方应该在IName接口中,但我相信这在C#中是不可能的。 在每个
interface IName
{
string Name { get; }
}
还有一些基类基类。此类的子类可以实现IName接口,但并非所有子类都可以实现
如果一个子系统实现了IName,我还希望重写ToString()方法,这与所有情况完全相同,如下所示:
public override string ToString()
{
return Name;
}
似乎重写ToString()的好地方应该在IName接口中,但我相信这在C#中是不可能的。
在每个类中实现ToString()似乎也是一个坏主意,因为它有很多代码冗余(而且浪费时间)
对于这种情况,什么是合适的解决方案?我建议创建第二个基类:
public abstract class BaseClass
{
// your base class implementation
}
public abstract class NamedBaseClass : BaseClass, IName
{
public string Name { get; set;}
public override string ToString()
{
return Name;
}
}
这样,如果您希望子级同时实现基类和IName,那么您应该继承NamedBaseClass。
根据您所说的“有些可能实现IName,有些可能不实现”,那么基类不应该实现IName,但您仍然应该有某种基本实现。这是我的解决方案
编辑:
要创建一个返回名称且与基类无关的类,则可以为此创建一个不相关的抽象实现:
public abstract class NameStringClass : IName
{
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
我建议创建第二个基类:
public abstract class BaseClass
{
// your base class implementation
}
public abstract class NamedBaseClass : BaseClass, IName
{
public string Name { get; set;}
public override string ToString()
{
return Name;
}
}
这样,如果您希望子级同时实现基类和IName,那么您应该继承NamedBaseClass。
根据您所说的“有些可能实现IName,有些可能不实现”,那么基类不应该实现IName,但您仍然应该有某种基本实现。这是我的解决方案
编辑:
要创建一个返回名称且与基类无关的类,则可以为此创建一个不相关的抽象实现:
public abstract class NameStringClass : IName
{
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
将cFoo视为具有IName的子类。和cBar父类,cBaz作为一个类,不实现IName
public interface IName
{
string Name { get; }
}
public class CBaz : CBar
{
}
public class CFoo : CBar, IName
{
public CFoo(string name)
{
Name = name;
}
public string Name { get; }
}
abstract public class CBar
{
public override string ToString()
{
if (this is IName)
{
var temp = (IName) (this);
return temp.Name;
}
else
{
return base.ToString();
}
}
}
[旧答案]
请注意,接口本质上是空的。您需要将接口视为具有更多合同含义的接口,这意味着实现此接口的人员需要实现此类签名的属性/方法/字段/等
对于可能由许多类共享的特定于实现的任务,抽象类更合适
当您需要解析某种逻辑时,您必须通过实现网关,某些实现必须发生,接口本质上是空模板。实现这一点最宽松的方法是通过一个抽象类,该抽象类同时包含name属性和ToString重写,然后从中继承所有后续类
同时你可以为cBar类考虑一个抽象类。以及调用base.ToString()的基本方法。
[旧答案的结尾]将cFoo视为拥有IName的子类。和cBar父类,cBaz作为一个类,不实现IName
public interface IName
{
string Name { get; }
}
public class CBaz : CBar
{
}
public class CFoo : CBar, IName
{
public CFoo(string name)
{
Name = name;
}
public string Name { get; }
}
abstract public class CBar
{
public override string ToString()
{
if (this is IName)
{
var temp = (IName) (this);
return temp.Name;
}
else
{
return base.ToString();
}
}
}
[旧答案]
请注意,接口本质上是空的。您需要将接口视为具有更多合同含义的接口,这意味着实现此接口的人员需要实现此类签名的属性/方法/字段/等
对于可能由许多类共享的特定于实现的任务,抽象类更合适
当您需要解析某种逻辑时,您必须通过实现网关,某些实现必须发生,接口本质上是空模板。实现这一点最宽松的方法是通过一个抽象类,该抽象类同时包含name属性和ToString重写,然后从中继承所有后续类
同时你可以为cBar类考虑一个抽象类。以及调用base.ToString()的基本方法。
[旧答案的结尾]添加一个基本实现,例如抽象类。您首先需要这样做,而不是调用
。Name
?有一个基本类(如上所述),但我不想在那里跳过ToString(),因为它会影响不在名称中实现的子类。是的,有。为了便于讨论,请假设有一个原因。了解原因会有所帮助。只是想解决一个x-y问题。添加一个基本实现,比如一个抽象类。您首先需要这个而不是调用.Name
?有一个基类(如上所述),但我不想在那里跳过ToString(),因为它会影响到未在名称中实现的子类。是的,有。为了便于讨论,请假设有一个原因。了解原因会有所帮助。只是想解决一个x-y问题。您可能应该将ToString
覆盖密封起来。您可能是对的,我以前从来没有密封过一个方法,所以我根本就没有想到这一点。谢谢你的提示!这似乎是一种不错的方法,但如果我想在多个基类(除了object之外不共享任何共同祖先)中实现IName,该怎么办?我必须对所有这些实现进行这样的实现…请参阅编辑以获取我的建议:)一旦为所有实现获得了NameStringClass,只需从它继承即可。您要求的是一个类实现来自两个抽象类的逻辑。。。这在C#(从2个类继承)中是不可能的。要求为从单个类继承的多个类运行特定逻辑就是要求一个抽象实现。。。因此,我似乎无法在这里找到代码复制的方法,或者至少以某种方式对其进行重构,以允许代码以某种方式存在于单个位置……您可能应该将ToString
覆盖密封起来。您可能是对的,我以前从未密封过一个方法,所以我根本就没有想到这一点。谢谢你的提示!这似乎是一个不错的方法,但如果我想在不止一个b中恳求IName呢