Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.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#,我创建了这个界面: public interface IPhrase { int CategoryId { get; set; } string PhraseId { get; set; } string English { get; set; } string Romaji { get; set; } string Kana { get; set; } string Kanji { get; set; } } var phrases = db2

我创建了这个界面:

public interface IPhrase
{
    int CategoryId { get; set; }
    string PhraseId { get; set; }
    string English { get; set; }
    string Romaji { get; set; }
    string Kana { get; set; }
    string Kanji { get; set; }
}
var phrases = db2.Query<IPhrase>("SELECT * FROM Phrase", ans);
var eng = phrases[0].English; //**THIS WONT WORK**
这门课:

public class Phrase : IPhrase
{
    public Phrase()
    {
    }

    public int CategoryId { get; set; }
    public string PhraseId { get; set; }
    public string English { get; set; }
    public string Romaji { get; set; }
    public string Kana { get; set; }
    public string Kanji { get; set; }
}
在这里,此代码返回数据并将其类型转换为短语:

var phrases = db2.Query<Phrase>("SELECT * FROM Phrase", ans);
var phrases = db2.Query<IPhrase>("SELECT * FROM Phrase", ans);
var-phrases=db2.Query(“从短语中选择*”,ans);
var phrases=db2.Query(“从短语中选择*”,ans);

我想知道的是,在这里使用
IPhrase
短语是否有任何区别/优势?在本例中创建
IPhrase
接口有哪些优点(如果有的话)。这会导致更可读的代码吗?

接口是一种契约,它保证实现接口的任何类都将实现接口中定义的方法和属性。这允许您使用接口创建方法、列表等,这些方法、列表等接受实现接口的任何类,例如

public interface IExample
{
    int GetInt();
}

public void ProcessInt(IExample value)
{
    var tempInt = value.GetInt();
    // Do processing here
}

这允许将实现接口IExample的任何具体类传递给此方法。方法被保证任何传递的具体类都将实现方法GetInt。

接口是一个契约,它保证实现接口的任何类都将实现接口中定义的方法和属性。这允许您使用接口创建方法、列表等,这些方法、列表等接受实现接口的任何类,例如

public interface IExample
{
    int GetInt();
}

public void ProcessInt(IExample value)
{
    var tempInt = value.GetInt();
    // Do processing here
}

这允许将实现接口IExample的任何具体类传递给此方法。该方法保证任何传递的具体类都将实现方法GetInt。

在本地使用接口和具体对象之间没有区别,如您的示例所示。主要区别在于,当您将接口与具体类作为API中的参数或构造函数参数发送时,最好使用接口,以便实现解耦和可测试性

对于你的问题,简短的回答是不,没有区别,你是想使用接口还是具体的对象作为局部变量是你自己的选择(对你来说更容易理解)。不要忘记,字段和属性最好声明为接口,这样可以提供更大的灵活性

在使用具体对象而不是局部接口时,应该考虑的最后一件事是,您可能希望有一天更改为您提供该对象的方法的签名,以返回实现相同接口的另一种对象,在这种情况下,您也应该更改局部变量(即使情况不是很糟,而且很少发生,我也必须注意到),如以下示例所示:

interface IAnimal
{
    void Run();
}

class Cat : IAnimal
{
    public void Run()
    {
        //...
    }
}

class Dog : IAnimal
{
    public void Run()
    {
        //...
    }
}
如果您的代码中有一个方法返回您使用的
Cat

Cat GetAnimal()
{
    return new Cat();
}

Cat myAnimal = GetAnimal(); //note that here it is expected a Cat
myAnimal.Run();  
然后,如果将
GetAnimal
签名更改为返回
Dog
,则应更改代码以编译为:

Dog myAnimal = GetAnimal(); //note that here it is expected a Cat
myAnimal.Run();  
但是,如果您使用的是接口,则当方法的签名发生更改时,代码需要更改的可能性较小:

IAnimal myAnimal = GetAnimal(); //this is working whether a Cat or a Dog is received.
myAnimal.Run(); 

但是这种情况也很少发生。为愚蠢的猫狗示例感到抱歉!

在本地使用接口和具体对象之间没有区别,就像在您的示例中一样。主要区别是当您将接口与具体类作为API中的参数或构造函数参数发送时,最好在接口,以便实现解耦和可测试性

对于您的问题,简短的回答是“不”,没有区别,您是想使用接口还是具体对象作为局部变量是您自己的选择(您觉得更可读)。不要忘记,字段和属性最好声明为接口,这样可以提供更大的灵活性

在使用具体对象而不是局部接口时,应该考虑的最后一件事是,您可能希望有一天更改为您提供该对象的方法的签名,以返回实现相同接口的另一种对象,在这种情况下,您也应该更改局部变量(即使情况不是很糟,而且很少发生,我也必须注意到),如以下示例所示:

interface IAnimal
{
    void Run();
}

class Cat : IAnimal
{
    public void Run()
    {
        //...
    }
}

class Dog : IAnimal
{
    public void Run()
    {
        //...
    }
}
如果您的代码中有一个方法返回您使用的
Cat

Cat GetAnimal()
{
    return new Cat();
}

Cat myAnimal = GetAnimal(); //note that here it is expected a Cat
myAnimal.Run();  
然后,如果将
GetAnimal
签名更改为返回
Dog
,则应更改代码以编译为:

Dog myAnimal = GetAnimal(); //note that here it is expected a Cat
myAnimal.Run();  
但是,如果您使用的是接口,则当方法的签名发生更改时,代码需要更改的可能性较小:

IAnimal myAnimal = GetAnimal(); //this is working whether a Cat or a Dog is received.
myAnimal.Run(); 

但是这种情况也很少发生。对于愚蠢的猫和狗的例子,我很抱歉!

对于可以继承的对象:

  • 其他物体
  • 接口
  • 对象

    如果您有一个
    动物
    对象,那么
    对象可以继承它,因为它是一个动物

    对于对象继承,请考虑以下短语:
    我是一个……\u您的对象\u……

    接口

    有了一个接口,你可以把它看作是该对象的一个描述符。例如
    IWalkOnTwoLegs
    ICanSwim

    所以想想这个短语:
    我能行....\u你的界面..

    现在回答您的问题,使用或不使用界面会有什么不同吗?

    当然,在这种情况下不是这样,但是如果您扩展短语并创建一个
    问题
    对象和一个
    语句
    对象,并且它们继承自
    短语
    ,您可以选择返回所有短语(问题和语句)或仅为
    问题的短语
    或仅为
    语句

    您还可以对短语应用一个界面,上面写着
    iaminformench
    IAmInSpanish
    ,这样您就可以扩展
    SpanishPhrase
    FrenchPhrase
    对象。 现在您可以返回所有短语,无论它们是否为qu