문제
C# 3.0 도입 var
예어. 컴파일되면 컴파일러가 올바른 유형을 삽입합니다. 이것은 2.0 런타임에서도 작동한다는 것을 의미합니다. 여태까지는 그런대로 잘됐다. 하지만 다른 날에 나는 사건을 발견했다. var
키워드는 객체 만 대체하므로 충분히 구체적이지 않습니다. 다음과 같은 것이 있다고 말합니다.
var data = AdoMD.GetData(...); // GetData returns a DataTable
foreach (var row in data.Rows)
{
string blah = (string)row[0]; // it fails since it's of type object
}
내가 둘 다 사용하려고 할 때 지적 그리고 컴파일러는 그것이 유형 객체라고 말합니다. data.Rows
유형입니다 System.Data.DataRowCollection
. 다음 작품 :
var data = AdoMD.GetData(...); // GetData returns a DataTable
foreach (DataRow row in data.Rows)
{
string blah = (string)row[0]; // works since it now has the right type
}
이것은 VAR의 사용에 대한 의문이 아니며, 그에 대한 스레드가 있습니다. 여기.
Visual Studio 2008 SP1 BTW를 사용하고 있습니다.
편집 : 이제 올바른 코드가 첨부되었습니다.
해결책
나는 문제를 본다고 생각한다. DatarOwCollection은 비 게릭이므로 컴파일러가 아는 유일한 것은 유형 객체의 객체를 포함하는 것입니다. 그것이 일반적인 데이터 일프라라면 이것이 효과가 있었을 것입니다.
다른 팁
이것:
using System;
namespace Test
{
public class X
{
public String Bleh;
}
public class Y : X
{
public String Blah;
}
public static class Program
{
public static void Main()
{
var y = SomeFunctionThatReturnsY();
// y. <-- this gives me both Blah and Bleh in the dropdown
}
public static Y SomeFunctionThatReturnsY()
{
return new Y();
}
}
}
예상대로 작동하며 Visual Studio 2008에서 Bleh와 Blah를 모두 보여주는 Intellisense를 제공합니다.
뭔가 있어요 처럼 그게 또는 바로 그거죠 저것? 당신이 보여준 코드보다 지능적인 다른 것들이있을 수 있습니다.
실제 질문에 대답합니다. 유형의 철자와 사용의 유일한 차이점 var
, 어떤 경우에는 당신입니다 ~ 해야 하다 단순히 올바른 유형이 없을 때 var를 사용하십시오. 내가 착각하지 않은 경우 익명 유형을 사용할 때만 관련이 있습니다.
다른 차이가 없으며 컴파일러는 오른쪽과 같은 왼쪽에서 동일한 유형을 선택합니다.
편집하다: 감사합니다 @Telos 한 가지 차이점을 지적하기 위해서는 Var를 사용할 때 오른쪽의 표현식 유형이 왼쪽의 변수 유형을 지시하는 데 사용되기 때문에 변수에 선언 시간에 값을 부여해야한다는 것입니다. 손잡이. 유형을 철자 할 때 물론 값을주지 않도록 선택할 수 있습니다.
내 생각은 그게 다 somethingThatReturnsY
실제로입니다 선언 x를 반환합니다 - 실제로 y를 반환하더라도. 나는 당신이 선언한다면 기대합니다 y
~처럼 Y y = somethingThatReturnsY();
컴파일하지 못할 것입니다.
규칙 var
매우 간단합니다 (작동하는 경우 - 당신을 막을 수있는 다양한 제한이 있습니다. var x = null;
등.
당신이 생각한다면 var
실제로 잘못된 일을하고 있습니다. 짧지 만 완전한 프로그램을 게시하십시오.
콘솔 응용 프로그램에서 다음 코드로 이것을 재현하려고했습니다.
class Program
{
static void Main(string[] args)
{
var j = returny();
j.blah();
}
private static y returny()
{
return new y();
}
}
class x
{
}
class y : x
{
public void blah() { }
}
이것은 예상대로 작동하고 Intellisense는 정확하며 반사기 것을 보여줍니다 j
유형입니다 y
. 내 생각에 당신이 비린내를 경험한다면 여기에서 간단한 경우보다 더 복잡하다는 것입니다.
Visual Studio 2008 RTM도 사용하고 있습니다.
DataTable.rows는 internaldatacollectionbase를 구현하는 DatarOwCollection을 반환하여 ICOLLECTION 및 IENUMERABLE을 구현합니다. 코드
foreach(DataRow row in dt.Rows) { }
DatarOwCollection의 각 항목을 Datarow에 시전합니다. 당신은 그것을 변경하여 이것을 보여줄 수 있습니다
foreach(int row in dt.Rows) { }
컴파일하지만 유효하지 않은 결과를 던진다.
DatarOwCollection이 구현 된 경우 IEnumerable<DataRow>
그런 다음 컴파일하지 않고 Var를 사용하면 목록에 각 객체를 데이터로 입력합니다.
샘플 코드에 충분한 정보를 제공했다고 생각하지 않습니다. 나는 당신이 설명하는 행동을 모방하기 위해 작은 프로그램을 만들었습니다.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var y = SomeFunctionThatReturnsY();
MessageBox.Show(y.bla);
return;
}
private Y SomeFunctionThatReturnsY()
{
return new Y();
}
}
internal class X { }
internal class Y : X
{
public string bla = "Saw a Y, not an X";
}
그러나 출력은 var가 x가 아닌 Y 유형을 해결하고 있음을 분명히 보여줍니다.
당신은 당신의 함수가 y를 y 참조로 반환한다고 확신합니까? x 참조가 아닌가?
그것은 필요한대로 작동합니다. 컴파일러가 올바른 데이터 유형을 결정할 수 없을 때 객체 유형을 "개체"로 설정합니다.
Foreach 키워드를 사용하면 ienumerable 인터페이스를 통해 DaterowCollection에 액세스됩니다. Datarow에 액세스하는 데 사용되는 특정 방법을 전류라고하며 객체를 반환합니다. 따라서 VAR 키워드는 유형을 추론하기 위해 현재 메소드의 반환 값을보고 있습니다.