Если вы хотите, как Cells(Rows.Count, 1).End(xlUp).Row
, вы можете сделать это.
просто используйте следующий код:
using Excel = Microsoft.Office.Interop.Excel;
string xlBk = @"D:\Test.xlsx";
Excel.Application xlApp;
Excel.Workbook xlWb;
Excel.Worksheet xlWs;
Excel.Range rng;
int iLast;
xlApp = new Excel.Application();
xlWb = xlApp.Workbooks.Open(xlBk, 0, true, 5, "", "", true,
Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xlWs = (Excel.Worksheet)xlWb.Worksheets.get_Item(1);
iLast = xlWs.Rows.Count;
rng = (Excel.Range)xlWs.Cells[iLast, 1];
iLast = rng.get_End(Excel.XlDirection.xlUp).Row;
Джефф прав. Это все равно, что спросить, какой торт был бы в пустой коробке без метки.
В качестве альтернативы ответу Фортрана вы также можете сделать:
string TypeNameLower<T>(T obj) {
return typeof(T).Name.ToLower(CultureInfo.InvariantCulture);
}
string TypeNameLower(object obj) {
if (obj != null) { return obj.GetType().Name.ToLower(CultureInfo.InvariantCulture); }
else { return null; }
}
string s = null;
TypeNameLower(s); // goes to the generic version
Таким образом, C # выберет общий во время компиляции, если он знает достаточно о типе, который вы передаете.
if (o == null) return "null";
else return o.GetType().Name.ToLower();
простое решение простой задачи :-p
Насколько мне известно, вы не можете. Null указывает на отсутствие значения и не отличается для разных типов.
Как отмечают другие, вы не можете. На самом деле это хорошо известная проблема с языками, которые допускают чистые нулевые ссылки на объекты. Один из способов обойти это - использовать шаблон «Нулевой объект». Основная идея состоит в том, что вместо использования null
для пустых ссылок вы назначаете ему экземпляр объекта «ничего не делать». Например:
public class Circle
{
public virtual float Radius { get; set; }
public Circle(float radius)
{
Radius = radius;
}
}
public class NullCircle : Circle
{
public override float Radius
{
get { return float.NaN; }
set { }
}
public NullCircle() { }
}
Затем вы можете передать экземпляр NullCircle
вместо null
, и вы сможете проверить его тип, как в вашем коде.
Нет понятия, что нулевая строка отличается от нулевой. Массив отличается от нулевой строки. Изнутри своей функции вы не можете определить имя типа.
Более конкретно, экземпляр ссылочного класса (внутри) включает «указатель» на информацию о типе объекта. Когда ввод нулевой, такого указателя нет, поэтому информация о типе не существует.
Рассмотрим этот код:
public class MyClass1{}
public class MyClass2{}
public static void Test1()
{
MyClass1 one = null;
MyClass2 two = (MyClass2) (object) one;
one = new MyClass1();
//invalid cast exception
two = (MyClass2)(object) one;
}
Тип времени выполнения нулевого экземпляра - объект
, по крайней мере, с точки зрения безопасности типов.
Очень досадно, что C # не позволяет сделать такое определение. И это не похоже на вопрос, какой торт у вас будет в пустой коробке - объект состоит из двух независимых компонентов - «воплощения» объекта и информации о классе, который использовался для создания объекта. Тот факт, что к этой информации нелегко получить доступ, является упущением со стороны разработчиков C #.
Все, что вы можете сделать в качестве определения, - это довольно уродливый метод:
void Method(object obj)
{
if(obj is int)
{
//obj is of the int type
}
else if(obj is SomeComplexType)
{
//obj is of the SomeComplexType type
}
}
Итак, вы можете видеть, что даже если объект имеет значение NULL, информация о его типе, тем не менее, перемещается вместе с объектом, она не теряется, вы просто не можете легко получить к ней доступ. Но это, мягко говоря, неудобно.
Выдать его длинным.
-121--4690971- Число операций strlen (слово)
зависит от:
слово
объявлено как постоянное (данные являются постоянными) слово
не изменяется. Пример:
char word[256] = "Grow";
for (i = 0; i < strlen(word); ++i)
{
strcat(word, "*");
}
В этом примере переменная word
изменяется в цикле:
0) «Рост» -- длина = = 4
1) «Рост *» -- длина = = 5
2) «Grow * *» -- length = = 6
Однако компилятор может факторизировать вызов strlen
, поэтому он вызывается один раз, если переменная word
объявлена как константа:
void my_function(const char * word)
{
for (i = 0; i < strlen(word); ++i)
{
printf("%d) %s\n", i, word);
}
return;
}
Функция объявила, что переменная word
является константными данными (фактически указатель на константные данные ). Таким образом, длина не изменится, поэтому компилятор может вызывать strlen
только один раз.
При возникновении сомнений вы всегда можете выполнить оптимизацию самостоятельно, что в этом случае может привести к более удобочитаемому коду.
-121--2750546-Если у вас есть объект сам по себе (скажем, как входной параметр для метода с объектом типа), без определения или общего типа, то найти тип невозможно. Причина проста: невозможно отправить сообщение (вызвать какой-либо метод) объекту для запроса о типе .
Возможны другие обходные пути, как вы видите в некоторых ответах, например, использование универсальных типов. В этом случае вы не запрашиваете объект Null, вы запрашиваете базовый тип для его типа.
// Uses the compiler's type inference mechanisms for generics to find out the type
// 'self' was declared with in the current scope.
static public Type GetDeclaredType<TSelf>(TSelf self)
{
return typeof(TSelf);
}
void Main()
{
// ...
Foo bar;
bar = null;
Type myType = GetDeclaredType(bar);
Console.Write(myType.Name);
}
Печатает:
Foo
Я разместил это также на аналогичную тему, надеюсь, вам это пригодится. ;-)
.