Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 定义强连接到接口的方法的正确方法_C# - Fatal编程技术网

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呢