【问题标题】:How to save class type as variable in c#?如何在c#中将类类型保存为变量?
【发布时间】:2013-07-09 14:47:18
【问题描述】:

在c#中,你能做这样的事情吗?

type typeOfInt = type(int);
int x = (typeOfInt)1;

基本上我想将类型存储为变量,因此我可以将变量用作强制转换。 我正在尝试这样做,因为在我的参数多态函数中,变量可能是 2 种类型中的 1 种。这两种类型都有我想使用的相同方法,但它不会让我使用它,因为它是变量类型。

    public static void SetFolderOrderValue<T>(T item, int value, Report reportObject)
    {
        if (!item.Exists)
        {
            reportObject.Log("The folder \"" + item.Name + "\" does not exist.");
            return;
        }
        try
        {
            item.SetProperty(folderOrderProperty, value);
            item.Update();
        }
        catch (SPException ex)
        {
            reportObject.Log("An error occurred when saving changes to the folder \"" + item.Name + "\". Maybe due to concurrent changes from another user. Please try again after a minute.\n" + Report.GetErrorInfo(ex));
        }
        catch (Exception ex)
        {
            reportObject.Log("An error occured with \"" + item.Name + "\":\n" + Report.GetErrorInfo(ex));
        }
    }

如果我至少可以将强制转换存储为一个值,那么我可以在函数中传递另一个布尔值,说明它是两种类型中的哪一种。

【问题讨论】:

  • 布尔值做多态性是个坏主意。你能在声明中添加必要的“where...”来获取基类,还是没有基类/接口
  • .net 中的所有对象都派生自 Object,因此所有对象都有返回 Type Object 的方法 GetType()。
  • @doctorlove,我不确定你的意思。我知道该类将是 SPFile 或 SPFolder。两者都有我上面使用的相同方法。但我不知道如何以目前使用的方式访问它们。
  • C# 泛型是编译时构造,但 GetType() 方法和类型检查是运行时的人,所以你不能在这里利用静态类型。您可以使用反射或 C# 动态按名称调用任何方法,或使用 as 运算符检查 item 类型与所有可能的类型

标签: c# parametric-polymorphism


【解决方案1】:

你说的是多态,所以用它吧。

如果您有 2 种具有 samecommon 方法的类型,并且您有一个或一组函数可以作用于它们,请定义一个描述该集合的 interface这两种类型之间共享的方法和:

如果你所说的类型被命名为SPFileSPFolder

public class SPFile : IMyNewInterface  {
   .....
}

public class SPFolder : IMyNewInterface  {
   ...
}

public static void SetFolderOrderValue<T>(T item, int value, 
              Report reportObject) where T : IMyNewInterface    {
     ...
}

【讨论】:

  • +1。但是,我在这里根本看不到对泛型的需求...只需将 T 替换为新接口并删除
  • @justnS。我没有看到有问题的必要性或不存在的证据,所以只需遵循 OP 的模式,希望他知道自己在做什么。
  • 公平点,当您知道您所期望的界面时,对我来说似乎没有必要。
  • 请注意,他还必须让 SPFile 和 SPFolder 都实现 IMyNewInterface
  • @Tigran 是的,但是对于从未使用过接口的人来说,向他们展示他们将不得不打开 SPFile/SPFolder 文件并添加公共类 SPFile : IMyNewInterface 除了更改SetFolderOrderValue,他们甚至可能无权更改这些类。
【解决方案2】:

不,你不能这样做。

我的回答假设 Tigran's answer 不适用,可能是因为您无法更改相关类型。

以下是实现您想要做的事情的一种方法:

var varOfTypeOne = item as TypeOne;
if(varOfTypeOne != null)
{
    varOfTypeOne.CallMethod();
    return;
}
var varOfTypeTwo = item as TypeTwo;
if(varOfTypeTwo != null)
{
    varOfTypeTwo.CallMethod();
    return;
}

另一种方法是通过dynamic 使用 DLR:

dynamic dynamicItem = item;
dynamicItem.CallMethod();

如果item 的实际类型未定义CallMethod,这将在运行时失败,因此您基本上会失去编译时安全性。

顺便说一句:采用没有约束的泛型参数的 void 方法通常可以简单地替换为非泛型方法,并且具有 object 作为参数类型。

【讨论】:

    【解决方案3】:

    是的,您可以保存类型,但这可能是代码异味。

    阅读http://msdn.microsoft.com/en-us/library/system.object.gettype.aspxhttp://msdn.microsoft.com/en-us/library/system.type.aspx

    这是一个例子

    int x = 1;
    var type = x.GetType();
    Console.WriteLine(type);
    

    【讨论】:

    • 这无助于 OP 实现他想要的。
    • 了解更多关于 Type 和 GetType 没有帮助吗?我注意到这是一种代码异味——希望将答案引向多态
    • 嗯,很明显,通过他的例子,他正在寻找类继承。但最后他说他想存储“类型演员”。您的示例仅存储一个字符串。
    • 也许它对 OP 没有帮助,但它可以帮助这个在谷歌上搜索这个特定答案的人,
    猜你喜欢
    • 1970-01-01
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 2023-03-29
    • 1970-01-01
    • 2011-01-28
    • 2018-09-23
    相关资源
    最近更新 更多