0

I have a List<object> which is a collection of various type of objects.

I am writing a helper method which will return a specific type of object. The helper method will accept type name as string parameter.

Note: I am using 3.5 framework.


PHP redirected page doesn't have a referral url

I have two site sitea.com and siteb.com

I need to redirect pages from sitea.com to siteb.com. The redirect script in sitea.com is

<?php
header("Location: http://siteb.com/somepage");
?>

The redirection is taking without any flaw. The functionality if fulfilled. But I have google analytics tracking on siteb.com which should show that the source is referral from sitea.com

I dug into web developer tools in google chrome and found that siteb.com doesn't send a referral header in the request.

How do i redirect my visitors from sitea.com to siteb.com which sends the referral headers on siteb.com.?

4

6 回答 6

8

如果您需要使用字符串作为参数,则不能依赖OfType<T>()扩展方法。幸运的是,它很容易模仿

public IEnumerable<object> OfType(this List<object> list, string typeName)
{
    return list.Where(x => x != null && x.GetType().Name == typeName);
}

正如@ChrisSinclair 在评论中指出的那样,该解决方案不管理转换、强制转换和继承/接口。强制转换(因为用户定义的转换运算符)和转换(因为TypeConverters 和IConvertible接口)有点棘手。对于简单(隐式)强制转换(如继承和接口),您可以使用:

public IEnumerable<object> OfType(this List<object> list, string typeName)
{
    Type type = Type.GetType(typeName);
    return list.Where(x => x != null && type.IsAssignableFrom(x.GetType()));
}

如何在运行时执行转换(即使使用 CUSTOM CONVERSION OPERATORS)

我发现我需要类似于我在这个答案中发布的代码,但我不得不稍微扩展它,这里有一个更好的实现来处理自定义强制转换和转换。

将所有内容放在一个CastExtensions类中(如果不这样做,则更新代码)然后enum为其选项声明这个小:

[Flags]
public enum CastOptions
{
    None = 0,
    ExcludeNulls = 1,
    UseConversions = 2
}

问题是 C# 通常是一种静态类型语言,这意味着几乎所有(关于类型)都必须在编译时知道(然后要执行转换,您必须知道要在编译时转换为的类型)。此函数处理简单的情况(如派生)和更复杂的情况(接口、自定义转换运算符 - 强制转换 - 和转换 - 在需要时)。

public static IEnumerable<object> OfType(this List<object> list, 
                                         string typeName, CastOptions options)
{
    Type type = Type.GetType(typeName);

    foreach (var obj in list)
    {
        if (Object.ReferenceEquals(obj, null))
        {
            if (options.HasFlag(CastOptions.ExcludeNulls))
                continue;

            yield return obj;
        }

        var objectType = obj.GetType();

        // Derived type?
        if (type.IsAssignableFrom(objectType))
            yield return obj;

        // Should we try to convert?
        if (!options.HasFlag(CastOptions.UseConversions))
            continue;

        // Castable?
        object convertedValue = null;

        try
        {
            var method = typeof(CastExtensions)
                .GetMethod("Cast", BindingFlags.Static|BindingFlags.NonPublic)
                .MakeGenericMethod(type);

            convertedValue = method.Invoke(null, new object[] { obj });
        }
        catch (InvalidCastException)
        {
            // No implicit/explicit conversion operators
        }

        if (convertedValue != null)
            yield return convertedValue;

        // Convertible?
        if (options.HasFlag(CastOptions.UseConversions))
        {
            try
            {
                IConvertible convertible = obj as IConvertible;
                if (convertible != null)
                    convertible.ToType(type, CultureInfo.CurrentCulture);
            }
            catch (Exception)
            {
                // Exact exception depends on the source object type
            }
        }
    }
}

请注意,转换可能等同于或不等同于强制转换,实际上它取决于实现和操作中涉及的确切类型(这就是您可以通过选项启用或禁用此功能的原因)。

这是运行时强制转换所需的一个小辅助函数:

private static T Cast<T>(object obj)
{
    return (T)obj;
}

我们可能会在运行时发出此代码(我想即使使用表达式,但我没有尝试)但是一个小的帮助方法将生成我们需要的代码(从对象转换为运行时已知的泛型类型)。请注意,此转换函数对于值类型不能按预期工作,例如:

int a = 1;
float a = Cast<float>(a); // Run-time error

这是因为(object)1不能转换为除此之外的任何其他int值(对于所有装箱值类型都是如此)。如果您使用的是 C# 4.0,则应将object参数更改为objdynamic一切都会按预期工作(适用于所有类型)。

于 2012-12-21T15:25:23.260 回答
2

Maybe something like that :

var ofTypeTypeA = myList.OfType<TypeA>();
于 2012-12-21T15:22:39.167 回答
0

一种干净的方法是强制用户将类型指定为类型,以避免应用程序中出现松散的字符串。

然后你可以使用泛型并只使用你感兴趣的类型。这也将允许调用者在以后使用 IEnumerable 时跳过强制转换。

所以代替这个:

List<object> newList = GetOfType(myList, "SomeObject");
// CAST!!
SomeObject someObject = newList[0] as SomeObject;
if (someObject != null)
    // use object

你会这样做:

IEnumerable<SomeObject> newList = myList.OfType<SomeObject>();
foreach (SomeObject someObject in newList){
    // no cast neccessary

如果您应该重命名类,这使得它在未来变得不敏感SomeObject(因为重构工具会选择类名而不是字符串)

于 2012-12-21T15:32:40.073 回答
-1

我想您需要将从列表中提取的单个对象转换为强类型对象。并且不要将所有列表都投给它。否则使用List<MyType>.

所以我会选择这个:How to cast to a type in C#

于 2012-12-21T15:32:03.530 回答
-1

您可以使用Enumerable.OfType

var input = new List<object>();
input.Add(1);
input.Add("foo");
var bar = input.OfType<string>();
于 2012-12-21T15:23:57.483 回答
-3

您可以使用 is 运算符(或传递类型并检查是否也使用 is)。以下是使用 is 运算符的示例:

foreach (var ctl in ControlsList)
{
    if (ctl is CheckBox)
        //Do this
    else if (ctl is TextBox)
        //DoThis
}

通过在参数中将类型作为字符串传递,您可以执行类似的操作来获取要测试的类型:

Type t = System.Type.GetType("System.Int32");
于 2012-12-21T15:25:22.240 回答